寻找一种从C++调用Java的便捷方法

Dan*_*ker 31 java java-native-interface swig invocation

似乎大多数与JNI(Java Native Interface)相关的文档或帮助程序库都涉及从Java调用本机代码.这似乎是它的主要用途,即使它能够更多.

我想主要在相反的方向上工作:通过向其添加一些Java库来修改现有的(相当大的)可移植C++程序.例如,我想让它通过JDBC调用数据库,或者通过JMS调用消息队列系统,或发送电子邮件,或调用我自己的Java类等.但是使用原始JNI这是非常不愉快和容易出错的.

所以我理想地想编写可以像C++/CLI一样调用CLR类的C++代码来调用Java类.就像是:

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;
Run Code Online (Sandbox Code Playgroud)

这样,我就不必通过传递名称和奇怪的签名字符串手动完成获取方法ID的工作,并且可以防止由未经检查的API调用方法引起的编程错误.实际上它看起来很像等效的Java.

NB.我还在谈论使用JNI!作为一项基础技术,它非常适合我的需求.它"在进行中"并且高效.我不想在一个单独的进程中运行Java并对它进行RPC调用.JNI本身很好.我只想要一个愉快的界面.

必须有一个代码生成工具来创建等效的C++类,命名空间,方法等,以完全匹配我指定的一组Java类所公开的内容.生成的C++类将:

  • 拥有接受其参数的类似包装版本的成员函数,然后执行必要的JNI voodoo来进行调用.
  • 以相同的方式包装返回值,以便以自然的方式链接调用.
  • 维护方法ID的每类静态缓存,以避免每次都查找它们.
  • 完全是线程安全的,可移植的,开源的.
  • 每次调用方法后自动检查异常并产生std C++异常.
  • 当我以通常的JNI方式编写本机方法时,也可以工作,但我需要调用其他Java代码.
  • 数组应该在原始类型和类之间完全一致.
  • 毫无疑问需要像global这样的东西来包装引用,当它们需要在本地引用框架之外生存时 - 再次,应该对所有数组/对象引用都一样.

这样一个免费的,开源的,可移植的库/工具是存在还是我在做梦?

注意:我发现了这个现有的问题,但在那种情况下,OP并不像我一样对完美的要求......

更新:关于SWIG的评论引发了我之前的问题,这似乎表明它主要是相反的方向,所以不会做我想要的.

重要

  • 这是关于能够编写操纵Java类和对象的C++代码,而不是相反(参见标题!)
  • 我已经知道JNI存在了(请参阅问题!)但是手工编写的代码到JNI API是不必要的冗长,重复,容易出错,在编译时没有类型检查等.如果你想缓存方法ID和类对象它更加冗长.我想自动生成C++包装类,为我处理所有这些.

更新:我已经开始研究自己的解决方案了:

https://github.com/danielearwicker/cppjvm

如果这已经存在,请告诉我!

NB.如果您正在考虑在自己的项目中使用它,请自由,但请记住,现在代码已经有几个小时了,到目前为止我只编写了三个非常不费力的测试.

And*_*mas 17

是的,现有的工具正是这样做的 - 为Java类生成C++包装器.这使得在C++中使用Java API更加透明和愉快,成本和风险更低.

我最常用的是JunC++离子.它成熟,强大而稳定.主要作者非常好,反应灵敏.不幸的是,它是一种商业产品,价格昂贵.

Jace是一个免费的开源工具,具有BSD许可证.自从我上次与杰斯一起比赛已经好几年了.看起来还有一些积极的发展.(我还记得十多年前原作者的USENET帖子,问你问的问题基本相同.)

如果需要支持从Java到C++的回调,那么定义实现Java接口的C++类会很有帮助.至少JunC++ ion允许您将这些C++类传递给采用回调的Java方法.我最后一次尝试jace,它不支持这个 - 但那是七年前.

  • 顺便说一句,我在谷歌搜索"C++ Java JNI Wrapper"这个术语时,我现在看到JunC++离开了结果的第22页!尚未发现Jace ...... (2认同)

小智 8

我是Codemesh语言集成产品的主要架构师之一,包括JunC++ ion.自1999年以来,我们一直在进行这种集成,并且它运行良好.最大的问题不是JNI部分.JNI繁琐且难以调试,但一旦你做对了,它大多只是继续工作.您不时会被JVM或操作系统更新破坏,然后您必须对产品进行微调,但总的来说它是稳定的.

最大的问题是类型系统映射以及一般可用性和目标解决方案之间的权衡.例如,您声明您不喜欢JACE将所有对象引用视为全局变量的事实.我们做同样的事情(有一些逃生舱),因为事实证明,这种行为最适合95%的客户,即使它会损害性能.如果您要发布API或产品,则必须选择使大多数人都能使用的默认值.选择本地引用作为默认选项是错误的,因为越来越多的人正在编写多线程应用程序,并且人们想要从其他语言使用的许多Java API本质上是多线程的,具有异步回调等.

我们还发现,您确实希望为人们提供基于GUI的代码生成器来创建集成规范.一旦他们指定了它,您就可以使用CLI版本将其集成到每晚构建中.

祝你的项目好运.要做到这一点,还有很多工作要做.我们花了几年的时间,我们仍然经常做得更好.