寻找一种方便的方式从C++中调用Java

 2023-01-19    371  

问题描述

似乎与JNI有关的大多数文档或辅助库(Java Native界面)都与从Java调用本机代码有关.这似乎是它的主要用途,即使它能够更多.

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

寻找一种方便的方式从C++中调用Java

.

因此,我理想地想编写可以像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.

nb.我仍在谈论使用JNI!作为基础技术,它非常适合我的需求.它是”流程”和高效的.我不想在单独的过程中运行Java并对其进行RPC调用. JNI本身很好.我只想要一个令人愉快的界面.

必须有一个代码生成的工具来制作等效的C ++类,名称空间,方法等.要与我指定的一组Java类所示的确切匹配.生成的C ++类将:

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

这样的免费,开源,便携式库/工具是否存在或我在做梦?

注意:我找到了现有的问题但是,在这种情况下的OP几乎没有我的完美要求…

更新:有关swig的评论使我进入以前的问题,这似乎表明它主要是相反的方向,因此不会做我想要的.

重要

  • 这是关于能够编写操纵Java类和对象的C ++代码,而不是相反(请参阅标题!)
  • 我已经知道JNI存在(请参阅问题!),但是JNI API的手写代码不必要地冗长,重复性,容易出错,并且在编译时间进行类型检查等.如果您想缓存方法, ID和班级对象它甚至更详细.我想自动生成C ++包装类别的类,这些类别为我照顾所有这些.

更新:我已经开始使用自己的解决方案:

如果已经存在,请让我知道!

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

推荐答案

是的,有些现有工具可以正当地做到这一点 – 生成Java类的C ++包装器.这使C ++中的Java API更加透明和愉快,成本和风险较低.

我使用的最多的是 junc ++ ion .它成熟,有力且稳定.主要作者非常好,反应迅速.不幸的是,这是一种商业产品,而且价格昂贵.

jace 是带有BSD许可证的免费开放式工具.自从我上次玩Jace以来已经好几年了.看起来仍然有一些积极的发展. (几十年前,我仍然记得原始作者的usenet帖子,基本上问您要问的问题.)

如果您需要支持从Java到C ++的回调,则定义实现Java接口的C ++类很有帮助.至少JUNC ++离子使您可以将此类C ++类传递给接听回调的Java方法.我上次尝试jace时,它不支持这一点 – 但那是七年前.

其他推荐答案

我是Codemesh语言集成产品的Prinicpal架构师之一,包括Junc ++ ion.自1999年以来,我们就一直在进行这种整合,而且效果很好.最大的问题不是JNI部分. JNI很乏味,很难进行调试,但是一旦您正确地做到了,它大部分就一直保持正常工作.时不时地,您会被JVM或操作系统更新打破,然后您必须微调产品,但总的来说它是稳定的.

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

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

祝您项目好运.正确的工作是很多工作.我们花了几年的时间,我们仍然会定期做得更好.

其他推荐答案

我遇到了几乎相同的问题,最终是我自己做的,也许这对某人有帮助.

它的运行时足迹( StringArray;然后使用StringArray [1] – > getBytes()或其他.

以上所述是小编给大家介绍的寻找一种方便的方式从C++中调用Java,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!

原文链接:https://77isp.com/post/25801.html

=========================================

https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。