C++ 移动开发跨平台解决方案

目录

1 Swig方案... 2

1.1 下载安装... 2

1.2 使用... 3

2 Djinni方案... 5

2.1 下载和安装... 5

2.2 使用... 6

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

       针对功能复杂的app开发,比较流行的方案一般是用c++开发跨平台的底层SDK供UI层调用。实现一套代码多个平台适配,架构图如下所示。这种架构就需底层SDK能自动生成桥阶层代码供不同平台UI层调用,很多开发人员还停留在手动写jni或者oc代码阶段,本文给出两种自动化跨平台解决方案以提高开发效率,一种使用Swig生成桥接层代码。另一种是使用Djinni生成桥阶层代码。Biz Logic层服务接口通过swig/djinni自动生成jni/oc 代码,供UI层开发人员使用。

      

1. Swig方案

SWIG (Simplified Wrapper and Interface Generator) ,即简化包以及接口生成器,SWIG读取带注释的C / C ++头文件并创建包装器代码,以使相应的C / C ++库可用于其他语言如Java、python、php等调用。

1.1 下载与安装

代码地址:https://github.com/maxep/swig-objc.git

Windows安装:http://www.swig.org/survey.html

1.2 使用

新建一个动态库工程,以下为该工程示例代码:

新建testSwigInterface.h,该.h用于编写接口类

class ITest

{

public:

    ITest() {}

    virtual ~ITest() {}

public:

    virtual int GetNumber() = 0;

};

 

新建test.h和test.cpp用于继承接口类。实现接口功能

test.h代码如下:

#include "testSwigInterface.h"

class Test: public ITest

{

public:

    Test() {}

    ~Test() {}

public:

    virtual int GetNumber();

};

 

#include "stdafx.h"

#include "test.h"

 

test.cpp代码如下

int Test::GetNumber()

{

    return 0;

}

 

要生成testSwigInterface 的Java接口,就需要编写.i文件。实战中一般用python写脚本自动生成.i文件。

test.i文件如下:

%module  api

%{

#include "testSwigInterface.h"

%}

%include "testSwigInterface.h" 

 

打开SWIG安装目录,如D:\soft\swig\win\swigwin-4.0.2

在命令行下进入到SWIG安装目录。下面步骤是将.i文件生成JAVA接口

命令:

swig -c++  -java -package com.example -outdir ./  -l../include test.i

-package 来指定JAVA包名如:com.example

-outdir 来指定生成的文件存放路径 ./表示当前路径下。

-l 用来连接.i文件所在的路径。

编译后输出有.java文件和wrap文件如下所示

 

打开Itest.java可看到自动生成的代码:

2. Djinni方案

Djinni是Dropbox开发的工具,可帮助利用C ++内置的代码发布到iOS和Android平台

2.1 下载

地址:https://github.com/dropbox/djinni.git

2.2 使用

我们将利用git子模块将Djinni添加为我们项目的依赖项。

先新建一个项目目录,进入目录,然后在Terminal中输入以下命令以将Djinni添加为子模块:

git init

git submodule add https://github.com/dropbox/djinni.git deps/djinni

 

和swig使用方式不太一样的是,使用djinni生成代码需要先新建一个helloworld.djinni

Djinni文件是IDL(接口描述语言)文件,这些文件列出了我们应用程序的跨平台C ++功能的计划。

hello_world = interface +c {

  static create(): hello_world;

  get_hello_world(): string;

}

create()方法将返回IDL文件中概述的方法的C ++对象的实例,而get_hello_world()函数将返回带有“ Hello World!”的字符串。和一天中的时间。

新建一个run_djinni.sh

这是将运行djinni命令的脚本,该脚本已根据我们应用程序所需的选项进行了自定义。我们将命名该文件run_djinni.sh并将其放置在项目的根目录中,以便轻松查找:

run_djinni.sh

#! /usr/bin/env bash

### Configuration

# Djinni IDL file location

djinni_file="helloworld.djinni"

# C++ namespace for generated src

namespace="helloworld"

# Objective-C class name prefix for generated src

objc_prefix="HW"

# Java package name for generated src

java_package="com.mycompany.helloworld"

### Script

# get base directory

base_dir=$(cd "`dirname "0"`" && pwd)

# get java directory from package name

java_dir=$(echo $java_package | tr . /)

# output directories for generated src

cpp_out="$base_dir/generated-src/cpp"

objc_out="$base_dir/generated-src/objc"

jni_out="$base_dir/generated-src/jni"

java_out="$base_dir/generated-src/java/$java_dir"

# clean generated src dirs

rm -rf $cpp_out

rm -rf $jni_out

rm -rf $objc_out

rm -rf $java_out

# execute the djinni command

deps/djinni/src/run \

   --java-out $java_out \

   --java-package $java_package \

   --ident-java-field mFooBar \

   --cpp-out $cpp_out \

   --cpp-namespace $namespace \

   --jni-out $jni_out \

   --ident-jni-class NativeFooBar \

   --ident-jni-file NativeFooBar \

   --objc-out $objc_out \

   --objc-type-prefix $objc_prefix \

   --objcpp-out $objc_out \

   --idl $djinni_file

运行Djinni脚本并生成JNI和Objective-C,C ++和Java接口以及Objective-C委托所需的所有文件:

$ sh ./run_djinni.sh

生成的代码文件在generate-src文件夹。

如此桥阶层代码就自动生成完毕,接下来我们只要继承接口类,来对接口功能做实现,创建两个新文件“ hello_world_impl.hpp”和“ hello_world_impl.cpp”:

hello_world_impl.hpp如下:

#include "hello_word.hpp"

 

namespace helloworld {

    class HelloWorldImpl : public helloworld::HelloWorld

    { 

    public:

        HelloWorldImpl();

        std::string get_hello_world();

    };

}

 

hello_world_impl.cpp如下:

 

#include "hello_word_impl.hpp"

#include <string>

namespace helloworld {

    std::shared_ptr<HelloWorld> HelloWorld::create()

    {

        return std::make_shared<HelloWorldImpl>();

    }

    HelloWorldImpl::HelloWorldImpl() {}

    std::string HelloWorldImpl::get_hello_world()

    {

        return "Hello World! ";

    }

}

 

 

 

 

 

猜你喜欢

转载自blog.csdn.net/GWB_superman/article/details/106891549