Java 本机接口 (JNI) 是否受 C++ ABI 兼容性问题影响?

2024-03-25

Java 本机接口 (JNI) 是否受 C++ ABI 兼容性问题影响?

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

我可以要求我的用户拥有 JRE 6 或更高版本,但我不能要求他们拥有任何特定的 C++ 运行时。

一位同事向我推荐了这篇博客文章:http://www.trilithium.com/johan/2005/06/static-libstdc/ http://www.trilithium.com/johan/2005/06/static-libstdc/建议不要使用动态加载的 C++ 代码。

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

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

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

我对此有几个问题。

首先,OpenJDK 会继续采取这种做法吗?

[EDIT:我在 OpenJDK 的构建开发邮件列表上问了这个问题。答案是肯定的,HotSpot 仍然静态链接 libstdc++,但显然“大多数 Linux 发行版都修补了这个问题”。另一位开发人员指出,这甚至不需要补丁:“设置 STATIC_CXX=false 应该足够了(默认为 true)。"]

其次,即使在这种情况下,同时加载两个不兼容的 libstdc++.so 真的是良性的吗?

第三,这种方法(隐藏 JDK 中的符号)是否解决了所有兼容性问题?

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

这听起来似乎问题无法解决。

话又说回来,也许 ABI 不兼容不再是问题了。这篇博客文章已有六年多了。另一个 stackoverflow 问题的答案(GCC ABI 兼容性 https://stackoverflow.com/questions/2801938/gcc-abi-compatibility)断言“自 gcc-3.4.0 起,ABI 向前兼容。”那成功了吗?

如果您对这些问题有任何指导,我将不胜感激。 (嘿,感谢您阅读所有这些!)

EDITS

我的问题太长了,所以我没有给出所有细节。针对威尔的评论:

  1. 我只需要调用外部“C”函数。 (例如我使用javah生成C头文件。)
  2. 我不需要与 JVM 中的 C++ 运行时交互。 (我基本上只需要将字符串发送到 C++ 库。)

我不知道。但这从未阻止我。

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

接下来,关于 JNI,首先您将调用 C 函数而不是 C++,我不相信 JNI 有任何类型的 C++ 绑定。因此,无论您想要使用什么 C++,都需要将其包装在 C 例程中才能与 Java 对话。

接下来,您的 C++ .so 将动态链接到操作系统,就像我猜的那样。期望 JNI 例程不能与动态链接的 .so 一起工作似乎是相当严厉的,而 C++ .so 应该没有什么不同。而且,毫无疑问,C++ 如此流行,但您无法动态链接到 C++ .so 似乎同样很严厉。因此,无论需要采取什么恶作剧来促进这一点,合理的假设是他们(tm)已经完成了允许这种情况发生的工作。

也就是说,当然不应该期望您使用的任何 C++ 都会与 Java 运行时中的 C++ 运行时进行任何交互。理想情况下,它们会和平共处。

鉴于此,假设这完全有效,您的 C++ 肯定会遇到 ABI 可移植性问题,因为它将动态链接,并且将受到操作系统安装的 C++ 运行时的支配。

所以,最后,我只是试一试,看看会发生什么。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 本机接口 (JNI) 是否受 C++ ABI 兼容性问题影响? 的相关文章

  • 如何在 Java 中测试一个类是否正确实现了 Serialized(不仅仅是 Serialized 的实例)

    我正在实现一个可序列化的类 因此它是一个与 RMI 一起使用的值对象 但我需要测试一下 有没有办法轻松做到这一点 澄清 我正在实现该类 因此在类定义中添加 Serialized 很简单 我需要手动序列化 反序列化它以查看它是否有效 我找到了
  • 方程“a + bx = c + dy”的积分解

    在等式中a bx c dy 所有变量都是整数 a b c and d是已知的 我如何找到整体解决方案x and y 如果我的想法是正确的 将会有无限多个解 由最小公倍数分隔b and d 但我只需要一个解决方案 我可以计算其余的 这是一个例
  • Javafx过滤表视图

    我正在尝试使用文本字段来过滤表视图 我想要一个文本字段 txtSearch 来搜索 nhs 号码 名字 姓氏 和 分类类别 我尝试过在线实施各种解决方案 但没有运气 我对这一切仍然很陌生 所以如果问得不好 我深表歉意 任何帮助将不胜感激 我
  • 两个静态变量同名(两个不同的文件),并在任何其他文件中 extern 其中一个

    在一个文件中将变量声明为 static 并在另一个文件中进行 extern 声明 我认为这会在链接时出现错误 因为 extern 变量不会在任何对象中看到 因为在其他文件中声明的变量带有限定符 static 但不知何故 链接器 瑞萨 没有显
  • 为什么这个字符串用AesCryptoServiceProvider第二次解密时不相等?

    我在 C VS2012 NET 4 5 中的文本加密和解密方面遇到问题 具体来说 当我加密并随后解密字符串时 输出与输入不同 然而 奇怪的是 如果我复制加密的输出并将其硬编码为字符串文字 解密就会起作用 以下代码示例说明了该问题 我究竟做错
  • Jersey 客户端请求中未设置 Content-Length-Header

    我正在使用 Jersey Client 访问网络服务 如下所示 response r accept MediaType TEXT PLAIN TYPE header content length 0 post String class 其中
  • 实例化类时重写虚拟方法

    我有一个带有一些虚函数的类 让我们假设这是其中之一 public class AClassWhatever protected virtual string DoAThingToAString string inputString retu
  • LINQ:使用 INNER JOIN、Group 和 SUM

    我正在尝试使用 LINQ 执行以下 SQL 最接近的是执行交叉联接和总和计算 我知道必须有更好的方法来编写它 所以我向堆栈团队寻求帮助 SELECT T1 Column1 T1 Column2 SUM T3 Column1 AS Amoun
  • 游戏内的java.awt.Robot?

    我正在尝试使用下面的代码来模拟击键 当我打开记事本时 它工作正常 但当我打开我想使用它的游戏时 它没有执行任何操作 所以按键似乎不起作用 我尝试模拟鼠标移动和点击 这些动作确实有效 有谁知道如何解决这个问题 我发现这个问题 如何在游戏中使用
  • 复制目录下所有文件

    如何将一个目录中的所有内容复制到另一个目录而不循环遍历每个文件 你不能 两者都不Directory http msdn microsoft com en us library system io directory aspx nor Dir
  • C 函数 time() 如何处理秒的小数部分?

    The time 函数将返回自 1970 年以来的秒数 我想知道它如何对返回的秒数进行舍入 例如 对于100 4s 它会返回100还是101 有明确的定义吗 ISO C标准没有说太多 它只说time 回报 该实现对当前日历时间的最佳近似 结
  • Java中的Object类是什么?

    什么是或什么类型private Object obj Object http download oracle com javase 6 docs api java lang Object html是Java继承层次结构中每个类的最终祖先 从
  • 有没有办法让 doxygen 自动处理未记录的 C 代码?

    通常它会忽略未记录的 C 文件 但我想测试 Callgraph 功能 例如 您知道在不更改 C 文件的情况下解决此问题的方法吗 设置变量EXTRACT ALL YES在你的 Doxyfile 中
  • 在 WPF 中使用 ReactiveUI 提供长时间运行命令反馈的正确方法

    我有一个 C WPF NET 4 5 应用程序 用户将用它来打开某些文件 然后 应用程序将经历很多动作 读取文件 通过许多插件和解析器传递它 这些文件可能相当大 gt 100MB 因此这可能需要一段时间 我想让用户了解 UI 中发生的情况
  • spring中如何使用jackson代替JdkSerializationRedisSerializer

    我在我的一个 Java 应用程序中使用 Redis 并且正在序列化要存储在 Redis 中的对象列表 但是 我注意到使用 RedisTemplate 会使用 JdkSerializationRedisSerializer 相反 我想使用 J
  • C# 中的 IPC 机制 - 用法和最佳实践

    不久前我在 Win32 代码中使用了 IPC 临界区 事件和信号量 NET环境下场景如何 是否有任何教程解释所有可用选项以及何时使用以及为什么 微软最近在IPC方面的东西是Windows 通信基础 http en wikipedia org
  • 对于某些 PDF 文件,LoadIFilter() 返回 -2147467259

    我正在尝试使用 Adob e IFilter 搜索 PDF 文件 我的代码是用 C 编写的 我使用 p invoke 来获取 IFilter 的实例 DllImport query dll SetLastError true CharSet
  • 如何使用 JSch 将多行命令输出存储到变量中

    所以 我有一段很好的代码 我很难理解 它允许我向我的服务器发送命令 并获得一行响应 该代码有效 但我想从服务器返回多行 主要类是 JSch jSch new JSch MyUserInfo ui new MyUserInfo String
  • C# 使用“?” if else 语句设置值这叫什么

    嘿 我刚刚看到以下声明 return name null name NA 我只是想知道这在 NET 中叫什么 是吗 代表即然后执行此操作 这是一个俗称的 条件运算符 三元运算符 http en wikipedia org wiki Tern
  • 如何从 Maven 存储库引用本机 DLL?

    如果 JAR 附带 Maven 存储库中的本机 DLL 我需要在 pom xml 中放入什么才能将该 DLL 放入打包中 更具体地举个例子Jacob http search maven org artifactdetails 7Cnet s

随机推荐