目录-关于swig
1.引用、指针、值作为参数,转换成java代码
在c/c++中,函数可以用许多不同的方法传递参数。
//指针
void test(struct Point *p);
//引用
void test(struct Point &p);
//通过值
void test(struct Point p);
以上方法通过SWIG转换后,都是对象实例引用
2.重载函数
.i接口文件
/*模块名see*/
%module See
//将自定义的代码包含在生成的文件中,例如编译生成的代码所需的头文件
%{
#include "test.h"
/*为什么还需要导入cpp,求解,是cmake缺少配置吗?????????????????????*/
#include "native-lib.cpp"
%}
%include "test.h"
test.h
extern int abc(int, int );
extern int abc(int );
native-lib.cpp
#include "test.h"
extern int abc(int a, int b) {
return 122;
}
extern int abc(int a) {
return 22;
}
cmakelist
cmake_minimum_required(VERSION 3.4.1)
#寻找swig
find_package(SWIG REQUIRED)
include(${SWIG_USE_FILE})
set(JAVA_GEN_PACKAGE "com.example.ndk2.jni")
string(REPLACE "." "/" JAVA_GEN_SUBDIR ${JAVA_GEN_PACKAGE})
set(JAVA_GEN_DIR ${Project_SOURCE_DIR}/../java/${JAVA_GEN_SUBDIR})
#寻找头文件
include_directories(${Project_SOURCE_DIR}/../cpp)
#文件输出目录
set(CMAKE_SWIG_OUTDIR ${JAVA_GEN_DIR})
set(CMAKE_SWIG_FLAGS -c++ -package ${JAVA_GEN_PACKAGE})
#在c ++模式下调用SWIG
set_property(SOURCE see.i PROPERTY CPLUSPLUS ON)
swig_add_library(See LANGUAGE java SOURCES See.i)
生成文件
public class See {
public static int abc(int arg0, int arg1) {
return SeeJNI.abc__SWIG_0(arg0, arg1);
}
public static int abc(int arg0) {
return SeeJNI.abc__SWIG_1(arg0);
}
}
3.类
.i文件
/*模块名see*/
%module See
//将自定义的代码包含在生成的文件中,例如编译生成的代码所需的头文件
%{
#include "A.h"
%}
%include "A.h"
A.h
#ifndef NDK2_A_H
#define NDK2_A_H
class A {
public:
void print() {
};
int value;
private:
void reset() {
};
};
#endif //NDK2_A_H
生成的java类
public class A {
private transient long swigCPtr;
protected transient boolean swigCMemOwn;
protected A(long cPtr, boolean cMemoryOwn) {
swigCMemOwn = cMemoryOwn;
swigCPtr = cPtr;
}
protected static long getCPtr(A obj) {
return (obj == null) ? 0 : obj.swigCPtr;
}
@SuppressWarnings("deprecation")
protected void finalize() {
delete();
}
public synchronized void delete() {
if (swigCPtr != 0) {
if (swigCMemOwn) {
swigCMemOwn = false;
SeeJNI.delete_A(swigCPtr);
}
swigCPtr = 0;
}
}
public void print() {
SeeJNI.A_print(swigCPtr, this);
}
public void setValue(int value) {
SeeJNI.A_value_set(swigCPtr, this, value);
}
public int getValue() {
return SeeJNI.A_value_get(swigCPtr, this);
}
public A() {
this(SeeJNI.new_A(), true);
}
}
4.异常处理
swig使用%exception预处理指令将c/c++异常转化成java。
.i接口文件
/*模块名see*/
%module See
//将自定义的代码包含在生成的文件中,例如编译生成的代码所需的头文件
%{
#include "A.h"
#include "A.cpp"
%}
/*在声明函数(%include)之前提添加*/
%exception getuid{
$action
if (!result){
jclass cls = jenv->FindClass("java/lang/OutOfMemoryError");
jenv->ThrowNew(cls, "Out");
return $null;
}
}
%include "A.h"
.h
#ifndef NDK2_A_H
#define NDK2_A_H
extern int getuid();
#endif //NDK2_A_H
.cpp文件
#include "A.h"
int getuid(){
return 0;
}
生成的cxx文件
SWIGEXPORT jint JNICALL Java_com_example_ndk2_jni_SeeJNI_getuid(JNIEnv *jenv, jclass jcls) {
jint jresult = 0 ;
int result;
(void)jenv;
(void)jcls;
{
result = (int)getuid();
if (!result){
jclass cls = jenv->FindClass("java/lang/OutOfMemoryError");
jenv->ThrowNew(cls, "Out");
return 0;
}
}
jresult = (jint)result;
return jresult;
}
调用
com.example.ndk2.jni.See.getuid();
输出结果
java.lang.OutOfMemoryError: Out
at com.example.ndk2.jni.SeeJNI.getuid(Native Method)
at com.example.ndk2.jni.See.getuid(See.java:13)
at com.example.ndk2.MainActivity.onCreate(MainActivity.java:27)
at android.app.Activity.performCreate(Activity.java:7136)
at android.app.Activity.performCreate(Activity.java:7127)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)