Java本机接口(JNI)是否受C ++ ABI兼容性问题的影响? [英] Is the Java Native Interface (JNI) affected by C++ ABI compatibility issues?

查看:299
本文介绍了Java本机接口(JNI)是否受C ++ ABI兼容性问题的影响?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Java Native Interface(JNI)是否受C ++ ABI兼容性问题的影响?

Is the Java Native Interface (JNI) affected by C++ ABI compatibility issues?

我正在开发一个Java应用程序。我想使用Java本机接口(JNI)来调用C ++库中的函数。我可以访问的C ++库的代码,我可以重建它,但我可能需要。 (例如,我可以静态链接C ++运行时。)

I am developing a Java application. I would like to use the Java Native Interface (JNI) to call functions in a C++ library. I have access to the code for the C++ library, and I can rebuild it however I may need to. (For example, I can statically link the C++ runtime.)

我可以要求我的用户拥有JRE 6或更大,但是我不能要求他们有任何

I can require my users to have JRE 6 or greater, but I can't require them to have any particular C++ runtime.

同事指示我访问此博客文章: http://www.trilithium.com/johan/2005/06/static-libstdc/ ,建议不要使用动态加载的C ++代码。

A coworker pointed me to this blog article: http://www.trilithium.com/johan/2005/06/static-libstdc/ which advises against using dynamically loaded C++ code.

另一位同事指出了这个错误报告: http://bugs.sun.com/bugdatabase/ view_bug.do?bug_id=4694590 ,其中详细介绍了如何在Java 1.4.2中解决这些问题。

Another coworker pointed me to this bug report: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4694590 which details how these issues were addressed back in Java 1.4.2.

问题的要点,据我所知,是libstdc ++的二进制接口经常改变。如果C ++应用程序加载用不同编译器构建的C ++共享库,则两个不兼容的libstdc ++库将同时加载到内存中。

The gist of the problem, as I understand it, is that the binary interface of libstdc++ often changes. If a C++ application loads a C++ shared library that was built with a different compiler, two incompatible libstdc++ libraries will be loaded into memory at the same time.

错误报告解释Java 1.4.2的解决方案:我们静态链接C ++运行时在JDK中并启用链接器脚本以隐藏来自libstdc ++和其他内部符号的符号。结果,这些符号对于JNI代码变得不可见,并且当某些本机代码需要调用C ++运行时,调用将使用适当的libstdc ++解析。所以仍然有两个libstdc ++,所以同时加载,但它应该是良性的。

The bug report explains the solution for Java 1.4.2: "We statically link the C++ runtime in JDK and enabled linker script to hide symbols from libstdc++ and other internal symbols. As the result, those symbols become invisible to JNI code, and when some native code needs to call into C++ runtime, the call will be resolved with the appropriate libstdc++.so. There are still two libstdc++.so being loaded at the same time, but it should be benign."

我有几个问题。

首先,OpenJDK是否继续采用这种方法?

First, does OpenJDK continue to take this approach?

[ EDIT:我在OpenJDK的build-dev邮件列表中提出了这个问题。答案是肯定的,HotSpot仍然静态链接libstdc ++,但显然大多数Linux发行版补丁。另一个开发人员注意到,这甚至不需要补丁:设置
STATIC_CXX = false应该足够了(默认为true)。]

[ I asked this question on OpenJDK's build-dev mailing list. The answer is yes, HotSpot still statically links libstdc++, but apparently "most Linux distros patch this out". Another developer notes that this doesn't even require a patch: "Setting STATIC_CXX=false should be enough (it defaults to true)."]

,甚至在这种情况下,是否真的有益于有两个不兼容的libstdc ++,所以同时加载?

Second, even in this case, is it truly benign to have two incompatible libstdc++.so loaded at the same time?

第三,这种方法JDK)解决了所有的兼容性问题?

Third, does this approach (to hide the symbols in the JDK) address all of the compatibility issues?

上面提到的博客文章警告说,针对不同ABI编译的代码不是二进制兼容的。后来,语言运行时支持通常依赖于一些共享的数据,例如访问某种锁或全局数据结构(类似于C程序需要共享的errno)。

The blog article referenced above warns that "code compiled against different ABIs is simply not binary compatible." And later that, "the language runtime support typically rely on some data being shared, e.g. to access some kind of lock or global data structure (similar to how C programs need a shared errno)."

这使得它听起来像问题无法解决。

This makes it sound like the problem cannot be solved.

然后,再次,也许ABI不兼容性不再是一个问题了。博客文章已超过六年。对另一个stackoverflow问题( GCC ABI兼容性)的一个回答断言自从gcc-3.4.0, ABI是向前兼容的。是否成功了?

Then again, maybe ABI incompatibility isn't a problem anymore. The blog article is over six years old. One answer for another stackoverflow question ( GCC ABI compatibility ) asserts that "Since gcc-3.4.0, the ABI is forward compatible." Has that been successful?

我会感谢您就这些问题提供任何指导。 (感谢您阅读所有这些!)

I'd appreciate any guidance on these issues. (And hey, thanks for reading all of this!)

EDITS

我的问题是变得很长,所以我没有给所有的细节。要处理Will的意见:

My question was getting pretty long, so I didn't give all the specifics. To address Will's comments:


  1. 我只需要调用externC函数。 (例如,我使用javah生成C头文件。)

  2. 我不需要与JVM中的C ++运行时交互。 (我基本上只需要将字符串发送到C ++库。)


推荐答案

知道。但是这从来没有阻止我。

I don't know. But that never stopped me.

首先,这取决于你想做什么。 JDK的静态链接背后的前提是提高实际JDK本身的可移植性。由于他们不能期望用户在他们特定的操作系统上重新编译JDK,他们需要一个机制来使最终的二进制可移植。显然静态链接固定了这个问题。

First, it depends on what you want to do. The premise behind the static linking of the JDK is to improve portability of the actual JDK itself. Since they can't expect users to recompile the JDK on their particular OS, they needed a mechanism to make the final binary portable. Apparently static linking fixed this problem.

接下来,关于JNI,首先你将调用C函数而不是C ++,我不相信JNI有任何类型的C捆绑。因此,无论你想要使用什么C ++,都需要在一个C程序中与Java对话。

Next, regarding JNI, first you'll be calling C functions and not C++, I don't believe JNI has any kind of C++ binding. So, whatever C++ you'll want to use will need to be wrapped in a C routine to talk to Java.

接下来,你的C ++ .so将动态链接到OS非常像正常我猜猜。看起来相当严厉的期望JNI例程不能使用动态链接的.so,而C ++ .so应该没有什么不同。并且,毫无疑问C ++是流行的,因为它似乎是类似的苛刻,你不能够动态链接到C ++ .so。因此,无论为了促进这一点,需要发生什么,这是一个合理的假设,他们(tm)已经做了工作,以允许这种情况发生。

Next, your C++ .so will dynamically link against the OS pretty much like normal I'm guessing. It's seems pretty draconian to expect a JNI routine to not work with a dynamic linked .so, and a C++ .so should be no different. And, no doubt C++ being as popular as it is, it seems similarly draconian that you would not be able to dynamically link against a C++ .so. So, whatever shenanigans that need to have taken place to facilitate this, it's a reasonable assumption that They(tm) have done the work to allow this to happen.

,肯定不应该期望,无论使用什么C ++将与Java运行时中的C ++运行时有任何交互。理想情况下,他们会和平共存。

That said, there should certainly be no expectation that whatever C++ you're using will have any interaction whatsoever with the C++ runtime in the Java runtime. Ideally, they'll simply peacefully co-exist.

鉴于这一点,假设这个工作在所有,你的C ++肯定会有ABI可移植性问题,因为它将动态链接,并将受到OS'es安装了C ++运行时。

Given that, assuming this works at all, your C++ will most certainly have the ABI portability issue, since it will be dynamically linking, and will be at the mercy of the OS'es installed C++ runtime.

所以,最后,我只是给它一个裂口,看看会发生什么。

So, in the end, I'd just give it a rip and see what happens.

这篇关于Java本机接口(JNI)是否受C ++ ABI兼容性问题的影响?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆