我正在尝试通过 swig 为这两个 C++ 函数生成 java 绑定(bind)
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
以限制其影响。您还可以在头文件中命名参数,并使用它来限制应用类型映射的位置。
关于java - Swig 类型映射 java 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26110908/