Swig typemap java对象

我试图通过swig为这两个c ++函数生成java绑定

C ++函数

void SetUserData(void* data); void* GetUserData() const; 

在java方面,我希望它看起来像这样

 setUserData(Object object); getUserData() //return java.lang.Object 

我希望void *指针指向我传递给它的任何java对象。 在我的swig文件中,我尝试添加这些行

 //swig file %typemap(jstype) void* "java.lang.Object"; %apply Object {void*}; 

我收到编译错误:b2Fixture.swig(22):警告453:无法应用(对象)。 没有定义任何类型图。 我不知道如何为此制作打字机。 有任何想法吗?

你可能想做:

 %apply jobject { void* }; 

因为%apply将在一个C ++类型上定义的类型映射复制到另一个C ++类型。 Object是Java类型,而不是C ++类型,因此没有要复制的任何类型映射。 另一方面, jobject是JNI的等价物。

另外假设你想要’正常’的GC语义(即不需要保留你传入的任何数据),你需要做更多的工作,例如:

 %module test %{ #include "test.hh" %} %apply jobject { void * }; %typemap(in) void * { void *old = getData(); if (old) JCALL1(DeleteGlobalRef, jenv, (jobject)old); $1 = JCALL1(NewGlobalRef, jenv, $input); } %typemap(out) void * { $result = (jobject)($1); } %include "test.hh" 

这为您的数据创建了一个新的全局参考,这可能是唯一阻止GC被释放的东西。

给定一个头文件:

 void setData(void *); void *getData(); 

和实施:

 #include "test.hh" namespace { void *d = nullptr; } void setData(void *d) { ::d = d; } void *getData() { return d; } 

这足以允许:

 public class run { public static void main(String[] argv) { System.loadLibrary("test"); Object example = "HELLO"; test.setData(example); System.out.println(test.getData()); } } 

工作正常。

如上所述,这些类型图非常难看 – 它们会影响void * 所有用法。 因此,如果你真的使用了这个,你会想要第二次使用%apply%clear来限制它们的影响。 您还可以在头文件中命名参数,并使用它来限制应用typemap的位置。

为了完整起见,这是使用JavaCPP执行此操作的另一种(更简单?)方法。 假设我们在C ++中有这样的GlobalData.h文件:

 class Data { public: JNIEnv* env; jobject data; Data(JNIEnv* env, jobject obj) : env(env), data(NULL) { } ~Data() { if (data != NULL) env->DeleteGlobalRef(data); } void SetUserData(jobject obj) { if (data != NULL) env->DeleteGlobalRef(data); data = env->NewGlobalRef(obj); } jobject GetUserData() { return data; } }; 

我们可以这样从Java中使用它:

 import org.bytedeco.javacpp.*; import org.bytedeco.javacpp.annotation.*; @Platform(include="GlobalData.h") public class GlobalData { static { Loader.load(); } public static class Data extends Pointer { public Data() { allocate(); } private native @Raw(withEnv=true) void allocate(); public native void SetUserData(@Raw Object obj); public native @Raw Object GetUserData(); } public static void main(String[] args) { Object someObject = new Object(); Data myData = new Data(); myData.SetUserData(someObject); Object sameObject = myData.GetUserData(); System.out.println(someObject); System.out.println(sameObject); } } 

输出显示someObjectsameObject指向同一对象的位置,例如:

 java.lang.Object@7aa06577 java.lang.Object@7aa06577