目录
1. Swig方案
1.1 下载与安装
1.2 使用
2. Djinni方案
2.1 下载
2.2 使用
针对功能复杂的app开发,比较流行的方案一般是用c++开发跨平台的底层SDK供UI层调用。实现一套代码多个平台适配,架构图如下所示。这种架构就需底层SDK能自动生成桥阶层代码供不同平台UI层调用,很多开发人员还停留在手动写jni或者oc代码阶段,本文给出两种自动化跨平台解决方案以提高开发效率,一种使用Swig生成桥接层代码。另一种是使用Djinni生成桥阶层代码。Biz Logic层服务接口通过swig/djinni自动生成jni/oc 代码,供UI层开发人员使用。
SWIG (Simplified Wrapper and Interface Generator) ,即简化包以及接口生成器,SWIG读取带注释的C / C ++头文件并创建包装器代码,以使相应的C / C ++库可用于其他语言如Java、python、php等调用。
代码地址:https://github.com/maxep/swig-objc.git
Windows安装:http://www.swig.org/survey.html
新建一个动态库工程,以下为该工程示例代码:
新建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可看到自动生成的代码:
Djinni是Dropbox开发的工具,可帮助利用C ++内置的代码发布到iOS和Android平台
地址:https://github.com/dropbox/djinni.git
我们将利用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
namespace
helloworld
{
std::shared_ptr<HelloWorld>
HelloWorld::create()
{
return
std::make_shared<HelloWorldImpl>();
}
HelloWorldImpl::HelloWorldImpl()
{}
std::string
HelloWorldImpl::get_hello_world()
{
return
"Hello World! ";
}
}