今天被同时问到java/android 使用swig编译c/c++ 代码类型转换。想起找个中文版swig看一下,虽然找到了,但也是基本是英文。
中文版首页的:http://www.swig.org/translations/chinese/index.html
中文版swig3.0文档:http://www.swig.org/Doc3.0/SWIGDocumentation.html#CONTENTS
我主要看了java方面的类型跟c/c++ 代码类型转换。
现在用几张图总结一下:
注意,swig包装C char类型作为一个角色。这种类型的指针和数组作为字符串包裹。签署char类型可以使用,如果你想把字符作为有符号数,而不是一个字符。还要注意,所有常量引用原始类型被视为如果他们通过价值。
int和C段的映射适用于32位应用程序用于32位jvm。没有完美的Java和C之间的映射为Java不支持所有的无符号C数据类型。然而,映射允许每个C的值从Java类型。
前一节中介绍了原始类型映射。类和结构体等非基本类型映射使用指针在C / c++端和存储到一个Java长变量的指针被代理类或类型的包装器类。这是否适用于编组为指针类型,通过引用或值。它还适用于任何未知的/不完整的类型,使用类型的包装器类。
总之,C / c++非基本指针类型转换为64位Java长类型,因此jlong JNI类型。Java类型是包装类代理类或类型。
如果您使用的是64位JVM您可能必须覆盖C长,但是可能不是C int默认映射。映射将依赖于系统,例如长需要重新映射在Unix LP64系统(64位长,指针,int 32位),但不是在微软64位Windows将使用P64 IL32(64位指针,int,长32位)模型。这可能是自动化在未来版本的痛饮。注意,Java一次编写到处运行理念适用于所有纯Java代码时,过渡到64位JVM。不幸的是它不会当然适用于JNI代码。
Java模块主要包括中列出的常见typemaps typemaps部分。有许多额外的typemaps为使用SWIG与Java是必要的。其中最重要的实现C / c++类型映射到Java类型:
注意,“在”typemap执法官JNI类型“JNI”typemap举行真正的C / c++类型相反的方向,”“typemap警察真正的C / c++类型JNI类型在“JNI”typemap举行。非基本类型的“在”和“出”typemaps负责铸件之间的C / c++和64位jlong类型指针。没有便携的方法把一个指针变成一个64位整数类型和方法swig主要是可移植的,但休息C / c++混叠的规则。总之,这些规则声明一个指向任何类型绝不能由一个指针引用其他任何不兼容的类型。下面的代码片段可能会帮助更好地理解混淆的规则:
short a;
short* pa = 0;
int i = 0x1234;
a = (short)i; /* okay */
a = *(short*)&i; /* breaks aliasing rules */
%typemap(in) struct Foo * %{
$1 = *(struct Foo **)&$input; /* cast jlong into C ptr */
%}
%typemap(out) struct Bar * %{
*(struct Bar **)&$result = $1; /* cast C ptr into jlong */
%}
struct Bar {...};
struct Foo {...};
struct Bar * FooBar(struct Foo *f);
SWIGEXPORT jlong JNICALL Java_exampleJNI_FooBar(JNIEnv *jenv, jclass jcls,
jlong jarg1, jobject jarg1_) {
jlong jresult = 0 ;
struct Foo *arg1 = (struct Foo *) 0 ;
struct Bar *result = 0 ;
(void)jenv;
(void)jcls;
(void)jarg1_;
arg1 = *(struct Foo **)&jarg1;
result = (struct Bar *)FooBar(arg1);
*(struct Bar **)&jresult = result;
return jresult;
}
注意,swig包装C char类型作为一个角色。这种类型的指针和数组作为字符串包裹。签署char类型可以使用,如果你想把字符作为有符号数,而不是一个字符。还要注意,所有常量引用原始类型被视为如果他们通过价值。
这些类型映射定义的“gotype typemap”。你可能改变typemap,或添加新值,控制C / c++类型是如何映射到类型。
由于输出参数的处理方式的局限性在swig,一个函数与输出参数将不会有多个返回值。相反,您必须通过一个指针到c++函数来告诉它在哪里存储输出值。在去,你供应一片地方的输出参数。
例如,假设您想将modf C数学库中()函数将x分为整体和部分部件(并返回整数部分的参数):
double modf(double x, double *ip);
您可以使用%申请指令:
%include
%apply double *OUTPUT { double *ip };
double modf(double x, double *ip);
%include
%apply signed char *OUTPUT {char *output};
void f(char *output);
%include "arrays_java.i";
int array[4];
void populate(int x[]) {
int i;
for (i=0; i<4; i++)
x[i] = 100 + i;
}
这些一维数组可以用作如果他们Java数组:
int[] array = new int[4];
example.populate(array);
System.out.print("array: ");
for (int i=0; i
java数组总是以引用的方式传递,因此一个函数对数组的任何更改将被调用的函数。这里是输出后运行这段代码:
array: 100 101 102 103
global_array: 100 101 102 103
%module example
%include "std_string.i"
%apply const std::string& {std::string* foo};
struct my_struct
{
std::string foo;
};
说了那么多,文档看了那么多,都是类型的转换。
还有一个很重要的特点就是。返回值时候可以以多参数的形式返回。
double[] dSource1 = new double[1];
double[] dSource2 = new double[1];
double[] dSource3 = new double[1];
double[] deditViewInputData = new double[3];
SourceCoord.XYZ_2(deditViewInputData[0],deditViewInputData[1], deditViewInputData[2],
dSource1, dSource2, dSource3);
上面是java代码,那么计算出来的值是放在三个double数组里面。
最后附上一个标准c++头文件
#ifndef _2013_H_
#define _2013_H_
#include
#include
#include
#ifdef SWIG
%include "std_string.i"
%include "typemaps.i"
%include "arrays_java.i"
%apply signed char[] {char*}
#endif // SWIG
class 2013
{
public:
2013(void);
~2013(void);
public:
int Auth(const std::string& m_N, const std::string& m_ID, const std::string& m_CODE, char *m_DATA);
int NetAuth(const std::string& m_JSH,const std::string& m_KEY,const std::string& m_PID,const std::string& m_Code,char *Return_Mes);
void EncodeBase64(const std::string& Src,int Src_len,char *base64code);
private:
void EncodeBase64(char *Src,int Src_len,char *base64code);
void DecodeBase64(const char *szCoded, char *Des,int &Des_len);
int CheckkCRC16( unsigned char *data, int Len);
};
#endif
我之前写android eclipse 部署编译swig以及一些知识博客
Android ndk开发swig编译jni接口 http://blog.csdn.net/qq_16064871/article/details/44658379
Android ndk开发swig编译jni接口配置文件(二) http://blog.csdn.net/qq_16064871/article/details/45110909
参考资料
http://blog.csdn.net/liminlu0314/article/details/6945452