我正在使用SWIG围绕某些C ++代码编写Java包装器。绑定现在正在运行,但不幸的是,在本机端创建的对象是免费的,而且速度太快。
自下而上的代码:
C ++: GitHub
namespace lm::ngram {
// ...
lm::base::Model* LoadVirtual(const char *file_name,
const lm::ngram::Config &config = lm::ngram::Config());
}
SWIG: GitHub
public class Model {
private com.github.jbaiter.kenlm.jni.Model cModel;
private String path;
//...
public Model(String path, Config config) throws ModelException {
this.path = path;
this.cModel = KenLM.LoadVirtual(path, config.getCConfig());
}
public long getOrder() {
return this.cModel.Order();
}
//...
}
Java: GitHub
@Test
public void getOrder() throws Exception {
Model model = new Model(toy0Url.getPath());
assertEquals(model.getOrder(), 3);
}
有问题的测试用例:GitHub
NullPointerException
由于model.cModel
为null
,测试失败并引发Model
。但是,当我在getOrder
构造函数中设置断点时,该字段设置正确,Model
返回预期结果。但是,只要构建器的范围被删除,我的null
类上的所有字段就会突然cModel
。 null
path
null
可能是因为我对SWIG的内存管理缺乏了解,但{{1}}字段{{1}}也是如此令人费解对我来说。
答案 0 :(得分:1)
您可能正在创建新对象以便与Java端一起使用(在本机端没有对该对象的引用)。 如果是真的,则需要指定此方法创建将遵循java lifetime / gc
的新对象%newobject lm::base::Model* LoadVirtual(const char *file_name,
const lm::ngram::Config &config = lm::ngram::Config());
您可以在swig文档中找到更多相关信息:http://www.swig.org/Doc1.3/Customization.html#ownership
答案 1 :(得分:0)
根本原因实际上是我的Java代码中的一个错误,与SWIG本身无关。
我有Model
类的两个构造函数,其中一个使用new Model(args)
而不是this(args)
调用另一个。当然,这会立即丢弃正确初始化的实例,并留下未初始化的对象(所有内容都为null
)。