使用C源代码在Java应用程序中的最简单方法是什么?

9
我发现了一个开源库,想在我的Java应用程序中使用。该库是用C语言编写的,在Unix/Linux下开发,而我的应用程序将在Windows上运行。它主要是数学函数库,据我所知,它不使用任何平台相关的东西,只是非常基本的C代码。此外,它并不大,不到5,000行。
在我的应用程序中使用该库的最简单方法是什么?我知道有JNI,但那需要在Windows下找到编译器来编译该库,与JNI框架保持最新,编写代码等等。虽然可行,但并不容易。有更简单的方法吗?考虑到库的规模较小,我想把它翻译成Java。有哪些工具可以帮助实现这一点?
编辑:
最终,我将需要的部分库翻译成了Java。目前为止,它大约占整个库的10%,尽管随着时间的推移可能会增加。C和Java非常相似,所以只花了几个小时。主要的困难是修复由于翻译错误引入的漏洞。
感谢大家的帮助。提出的解决方案都很有趣,当我需要链接到更大的库时,我会进一步研究它们。对于一个小的C代码片段,手动翻译是最简单的解决方案。

在继续进行应用程序之前,请查看Apache Commons Maths Library API文档 - Ande Turner
7个回答

11

Java GNU Scientific Library项目中,我使用了Swig来生成围绕C库的JNI包装器类。这是一个非常好的工具,可以为多种语言生成包装器代码,包括Python。强烈推荐。


5
你最好的选择可能是拿一本好的C语言书籍(K&R: The C Programming Language),泡一杯茶,开始翻译!我会怀疑相信一个翻译程序,往往最好的翻译者是你自己!如果你完成了这个任务,那么就完成了,不需要一直重做。如果该库是开源的,则需要仔细检查许可证。另一个要考虑的问题是,在翻译中总会存在一定的风险和潜在错误元素,因此可能需要考虑编写一些测试以确保翻译正确。
是否有JAVA等价的数学函数?
正如你所评论的那样,JNI方法是可行的,至于c编译器,你可以使用“Bloodshead Dev-c ++”,但对于约5000行代码来说,这需要付出很多努力。

4

我会编译并使用JNA。

JNA(Java Native Access)基本上在运行时完成JNI编译时的工作,并且不需要任何非Java代码(也没有太多Java代码)。

我不知道它在你的情况下的性能或可用性如何,但我会尝试一下。


我已经多年没有接触Java了,但我记得它被称为JNI-Java本地接口。如果他们改了名字,请告诉我。 - Man Vs Code
1
@ManVsCode,你可能想要删除那个备注,它没有意义。请重新阅读答案。 - Maarten Bodewes

1

你确定要使用C库吗?即使它很小?

一旦64位变得更加普遍,您将需要开始构建/部署32位和64位版本的库。根据C代码的情况,您可能需要更新代码以使其构建为64位。

如果C库很简单,那么将C库移植到纯Java可能会更容易,而不必处理构建/部署JNI库、C库和Java代码。


0

确实,JNA看起来很不错,它比直接使用JNI需要更少的努力。但无论如何,您都会失去平台独立性,而且由于您可能只使用其中的一小部分,因此您可以考虑翻译您实际需要的内容。


0

嗯,有AMPC。它是一个C编译器,可在Windows、MacOS X和Linux上编译C代码成Java字节码(这种代码可以在Java虚拟机上运行)。

AMPC

然而,它是商业软件,每个许可证需要199美元。我怀疑这是否值得你去做;) 我不知道有没有类似的免费编译器。

另一方面,Java和C很相似。您可以将C代码重构为Java代码(结构体可以被公共实例变量的对象所替代),指针操作通常可以转换为其他东西(例如数组操作)。但我想你可能不想浏览5000行的代码吧?

使用JNI会使代码依赖于平台,但是如果你说它是平台无关的C语言,那么你的Java代码就没有理由依赖于平台。另一方面,根据这些计算的成本如何,使用JNI实际上可能会为您带来性能提升,因为在原始数字计算吞吐量方面,C仍然可以在速度上击败Java。然而,JNI调用非常昂贵,因此如果计算只是一个非常简单、快速的计算,JNI调用本身可能需要同样长的时间(甚至更长),这种情况下使用JNI将不会给您带来任何好处,反而会减慢您的应用程序并导致内存开销。


-2

你尝试过使用:

System.loadLibrary("mylibrary.dll");

不确定这是否适用于纯C库,但可能值得一试。 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接