【发布时间】:2011-11-24 04:01:40
【问题描述】:
似乎大多数与 JNI(Java 本机接口)相关的文档或帮助程序库都与从 Java 调用本机代码有关。这似乎是它的主要用途,尽管它的功能更多。
我主要想朝相反的方向工作:通过添加一些 Java 库来修改现有的(相当大的)可移植 C++ 程序。例如,我想让它通过 JDBC 调用数据库,或者通过 JMS 调用消息队列系统,或者发送电子邮件,或者调用我自己的 Java 类等。但是对于原始 JNI,这是非常不愉快且容易出错的。
因此,理想情况下,我希望编写可以像 C++/CLI 调用 CLR 类一样轻松调用 Java 类的 C++ 代码。比如:
using namespace java::util::regex; // namespaces mapped
Pattern p = Pattern.compile("[,\\s]+");
array<java::lang::String> result =
p.split("one,two, three four , five");
for (int i=0; i < result.length(); i++)
std::cout << result[i] << std::endl;
这样,我就不必manually do the work of getting the method ID by passing the name and the weird signature strings,并且可以避免因调用方法的未经检查的 API 引起的编程错误。事实上,它看起来很像等效的 Java。
注意。我仍在谈论使用 JNI! 作为一项底层技术,它非常适合我的需求。它是“进行中的”并且非常高效。我不想在单独的进程中运行 Java 并对它进行 RPC 调用。 JNI 本身很好。我只想要一个愉快的界面。
必须有一个代码生成工具来生成等效的 C++ 类、命名空间、方法等,以完全匹配我指定的一组 Java 类所公开的内容。生成的 C++ 类将:
- 具有接受类似包装版本的参数的成员函数,然后执行必要的 JNI 巫术来进行调用。
- 以相同的方式包装返回值,这样我就可以以自然的方式链接调用。
- 维护每个类的方法 ID 静态缓存,以避免每次都查找它们。
- 完全线程安全、可移植、开源。
- 在每次方法调用后自动检查异常并产生一个标准 C++ 异常。
- 当我以通常的 JNI 方式编写本机方法但我需要调用其他 Java 代码时也可以使用。
- 数组应该在基本类型和类之间完全一致地工作。
- 毫无疑问,当引用需要在本地引用框架之外生存时,它们需要像全局这样的东西来包装引用 - 同样,所有数组/对象引用的工作方式应该相同。
这样一个免费的、开源的、可移植的库/工具是否存在,还是我在做梦?
注意:我找到了this existing question,但在那种情况下,OP 并没有我对完美的要求那么严格......
更新:关于 SWIG 的评论将我引至 this previous question,这似乎表明它主要是关于相反的方向,因此不会做我想做的事。
重要
- 这是关于能够编写操作 Java 类和对象的 C++ 代码,而不是相反(见标题!)
- 我已经知道 JNI 存在(见问题!)但是 JNI API 的手写代码不必要地冗长、重复、容易出错、在编译时没有类型检查等。如果你想缓存方法ID 和类对象更加冗长。我想自动生成 C++ 包装类来为我处理所有这些。
更新:我已经开始研究自己的解决方案:
https://github.com/danielearwicker/cppjvm
如果这已经存在,请告诉我!
注意。如果您正在考虑在自己的项目中使用它,请随意,但请记住,现在代码已经有几个小时了,到目前为止我只写了三个非常不费力的测试。
【问题讨论】:
-
有 SWIG 虽然我只在 C 和 Python 中使用过它...... 很久 以前。
-
查看更新:SWIG 显然没有这样做。
-
您想在哪个编译器/解释器中执行您的程序,C 还是 Java?如果是 Java,则无法使用 JNI 进行反向操作。
-
我已经在标签中添加了 swig,以防有人可以澄清。
-
@Naved - 我不明白你的问题:我想在本机编译的 C++ 中执行 C++ 部分(像往常一样)和 JVM 中的 Java 部分,并将两者与 JNI/调用。我只是不想手动做所有的 JNI 废话。
标签: java java-native-interface swig invocation