在Java应用程序中使用C源代码的最简单方法是什么?
我找到了要在Java应用程序中使用的开源库。该库是用C编写的,并且是在Unix / Linux下开发的,我的应用程序将在Windows上运行。它是一个主要包含数学函数的库,据我所知,它不使用任何依赖于平台的内容,它只是非常基本的C代码。而且,它不是那么大,少于5,000行。
在我的应用程序中使用库的最简单方法是什么?我知道这里有JNI,但这涉及到找到一个编译器来在Windows下编译该库,了解JNI框架的最新知识,编写代码等。可行,但并不那么容易。有没有更简单的方法?考虑到库的大小,我很想将其转换为Java。有什么工具可以吗?
编辑
最后,我将需要的库部分翻译成Java。到目前为止,它大约占库的10%,尽管它可能会随着时间的推移而增加。 C和Java非常相似,因此只花了几个小时。主要困难是修复翻译错误中引入的错误。
感谢大家的帮助。提出的解决方案似乎都很有趣,当我需要链接到较大的库时,我将对其进行研究。对于一小段C代码,手动翻译是最简单的解决方案。
解决方案
回答
最好的选择是喝杯好书(K&R:C编程语言)喝杯茶,然后开始翻译!我会对信任翻译程序持怀疑态度,但更多时候不是最佳翻译者就是我们自己!如果我们执行此操作,则说明已完成,而无需继续进行此操作。如果该库是开源的,可能会有些复杂,我们需要仔细检查许可证。要考虑的另一点是,翻译中总会有一些风险和潜在错误,因此可能有必要考虑编写一些测试以确保翻译正确。
没有JAVA等价的Math函数吗?
正如我们自己评论的那样,JNI方式是可行的,因为对于c编译器,我们可能会使用'Bloodshead Dev-c ++'可能有效,但是对于大约5000行来说,这是很大的努力。
回答
我会编译它并使用JNA。
JNA(Java本机访问)在运行时基本上是编译时的JNI,并且不需要任何非Java代码(也不需要太多Java)。
对于情况,我不知道它的性能或者可用性,但请尝试一下。
回答
在Java GNU科学库项目中,我使用Swig围绕C库生成了JNI包装器类。很棒的工具,并且还可以生成多种语言(包括Python)的包装器代码。强烈推荐。
回答
我们是否尝试过使用:
System.loadLibrary("mylibrary.dll");
不知道这是否适用于纯C库,但值得一试。 :)
回答
确实,JNA看起来令人印象深刻,与直接使用JNI相比,它需要的精力更少。但是无论如何,我们都将失去平台独立性,并且由于我们可能只使用了平台独立性的一小部分,因此我们可以考虑翻译我们实际需要的内容。
回答
好吧,这里有AMPC。它是用于Windows,MacOS X和Linux的C编译器,可以将C代码编译为Java Byte Code(在Java虚拟机上运行的那种代码)。
AMPC
但是,它是商业性的,每个许可证的价格为199美元。我怀疑这是否能为我们带来回报;)我不知道像这样的免费编译器。
OTOH,Java和C非常相似。我们可能可以将C代码重构为Java(可以用具有公共实例变量的对象替换结构),并且指针操作通常可以转换为其他内容(例如,数组操作)。尽管我猜我们不想遍历5,000行代码,对吗?
使用JNI使代码依赖于平台,但是,如果我们说它是独立于平台的C,则没有理由为什么Java代码应依赖于平台。 OTOH,根据这些计算的成本,使用JNI可能会为我们带来性能上的提升,因为就原始数字处理吞吐量而言,C的速度仍可以击败Java。但是,JNI调用非常昂贵,因此,如果计算只是一个非常简单,快速的计算,则JNI调用本身可能要比执行的计算花费相同的时间(甚至更长),在这种情况下,使用JNI不会给我们带来任何好处,但会减慢速度关闭应用程序并导致内存开销。
回答
即使很小,我们确定要使用C库吗?
一旦64位变得更加普遍,我们还需要开始构建/部署32位和64位版本的库。并且,根据C代码的不同,我们可能需要更新代码以将其构建为64位,也可能不需要。
如果C库很简单,那么将C库移植到纯Java而不用处理JNI库,C库和Java代码的构建/部署可能会更容易。