我想主要在相反的方向上工作:通过添加一些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;
这样,我就不需要手动通过传递名称和奇怪的签名字符串来获取方法ID的工作,并且可以避免由于调用方法的未经检查的API导致的编程错误。实际上,它看起来很像等效的Java。
注意:我仍在谈论使用JNI!作为底层技术,它非常适合我的需求。它是“进程内”且高效的。我不想在单独的进程中运行Java并进行RPC调用。JNI本身很好。我只是想要一个愉快的接口。
必须有一个代码生成工具来生成相当的C++类、命名空间、方法等,以完全匹配我指定的一组Java类所公开的内容。生成的C++类将:
- 拥有接受类似包装过的参数的成员函数,然后进行必要的JNI操作进行调用。
- 以相同方式包装返回值,以便我可以自然地链接调用。
- 维护每个类的静态方法ID缓存,以避免每次查找。
- 完全线程安全,可移植,开源。
- 在每个方法调用后自动检查异常并产生std C++异常。
- 也适用于我以通常的JNI方式编写本机方法,但需要调用其他Java代码时。
- 数组应在基本类型和类之间完全一致地工作。
- 毫无疑问,当引用需要在本地引用框架之外存活时,需要类似全局的东西来包装引用-同样适用于所有数组/对象引用。
是否存在这样一个免费、开源、可移植的库/工具?还是我在做梦?
注意:我发现this existing question,但那个问题中的OP要求远不如我这么苛刻...
更新:关于SWIG的评论引导我看到了this previous question,它似乎主要涉及相反的方向,因此不能满足我的需求。
重要提示:
- 这是关于能够编写操作Java类和对象的C++代码,而不是相反的(请看标题!)
- 我已经知道JNI的存在(请看问题!),但手写JNI API的代码冗长、重复、容易出错,在编译时没有类型检查等。如果你想缓存方法ID和类对象,它甚至更加冗长。我希望自动生成C++包装类来为我处理所有这些事情。
更新:我已经开始着手解决自己的问题:
https://github.com/danielearwicker/cppjvm
如果已经存在,请告诉我!
注意:如果您考虑在自己的项目中使用此代码,请放心,但请记住,现在的代码只有几个小时的历史,并且我目前只编写了三个非常简单的测试。