我有过早收集垃圾的问题。我在SWIG文档中找到了一个很好的solution来解决此类问题。但是我遇到了问题,因为我有静态工厂方法,无法访问非静态参考字段。
将推荐的SWIG解决方案应用于下面的C ++代码
struct Child {
};
struct Parent {
static Parent* create(Child& child);
};
像
那样破坏了Java代码public static Parent create(Child child) {
long cPtr = SampleJNI.Parent_create(getCPtrAndAddReference(child), child);
return (cPtr == 0) ? null : new Parent(cPtr, false);
}
此代码已损坏,因为Parent.create(Child child)
是静态的,但Parent.getCPtrAndAddReference(Child child)
不是。我正在思考两种解决方案中的一种。
第一个是找到生成类似
的方法public static Parent create(Child child) {
long cPtr = SampleJNI.Parent_create(Child.getCPtr(child), child);
return (cPtr == 0) ? null : new Parent(cPtr, false, child)/* call of alternative constructor created with typmap(javabody) */;
}
但我不知道该怎么做。
第二个解决方案是使用SetObjectField
调用在JNI端实现分配。我确实知道如何做到这一点,但如果可能的话我宁愿选择第一个解决方案。
答案 0 :(得分:1)
尝试这样的事情:
%newobject Parent::create;
%typemap(javacode) Parent %{
private Child childReference;
%}
%typemap(javaout) Parent* create(Child&) {
long cPtr = $jnicall;
if (cPtr == 0) {
return null;
} else {
Parent p = new Parent(cPtr, $owner);
p.childReference=child;
return p;
}
}
这将向Parent
添加字段,该字段将存储对child的引用,并在创建时保存引用。
%newobject
说java在垃圾收集这个项目时删除C对象。不要忘记它,否则你会有内存泄漏。