问题标签 [binary-compatibility]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
4 回答
817 浏览

c++ - 更改类私有数据成员的顺序是否会破坏 ABI

我有一个类,其中包含许多私有数据成员(其中一些是静态的),由虚拟和非虚拟成员函数访问。没有内联函数,也没有友元类。

在这种情况下,更改私有数据成员的顺序是否会破坏 ABI?


编辑
类型没有改变,只有成员的顺序。也没有使用位标志。该代码用作共享库,没有静态链接到该代码。我在 Linux 上,编译器是 gcc-3.4.3 和 gcc-4.1

0 投票
2 回答
236 浏览

dependencies - 包括不同版本的 glib 头文件

如果有两个源文件ac和bc:ac包含glib-2.6.6的glib.h,bc包含glib-2.12的glib.h

然后我编译它们并将它们链接在一起并生成目标程序。假设 ac 没有使用 v2.6 之后引入的任何新功能,包含不同版本的 headers 会导致任何问题吗?如果是这样,什么时候会出现这样的问题?

0 投票
3 回答
304 浏览

java - Java 二进制兼容性 - RFC 关于使用 invokevirtual 语义对协变返回类型提出的解决方案

我正在尝试开发 API。作为这种演变的一部分,我需要将方法的返回类型更改为子类(专业化),以便高级客户能够访问新功能。示例(忽略丑陋的:

我现在想要像这样拥有 ExtendedEntity、Intf2 和 Main:

但是,由于方法返回类型是其签名的一部分,因此已使用先前版本的代码编译的客户端显示链接错误(找不到方法 iirc)。

我想做的是向 Main 添加一个具有不同返回类型的方法。这两种方法(一种返回超类型,一种返回子类型)应映射到相同的实现方法(返回子类型)。注意 - 据我了解,JVM 允许这样做,但 Java 规范不允许这样做。

我的解决方案似乎在滥用(我对此无话可说)Java 类系统来添加所需的接口。

现在旧客户端将正确的方法返回到 invokevirtual 查找(因为具有正确返回类型的方法存在于类型层次结构中)并且实际工作的实现将是返回子类型 Intf2 的实现。

似乎有效。在我可以设计的所有测试中(除了反射-但我不在乎那一点)它确实有效。
它会一直有效吗?我的推理(关于调用虚拟)是否正确?

还有另一个相关的问题——是否有工具可以检查“真正的”二进制兼容性?我发现的唯一方法是单独查看每种方法,但没有考虑类型层次结构。

谢谢,
冉。

编辑-我尝试过并发现“不太好”的工具(不考虑类型层次结构):

  1. 克利尔 0.6。
  2. IntelliJ“APIComparator”插件。

Edit2 - 当然,我的客户被禁止为我的接口创建实现类(想想服务)。但是,如果您希望示例完整,请考虑抽象类(用于 Main)而不是接口。

0 投票
4 回答
281 浏览

linux - 我应该在哪个 Linux 发行版上链接以获得最佳的二进制兼容性?

我想知道在链接应该在尽可能多的发行版上针对共享库工作的二进制文件时,哪个 Linux 发行版最好(即引入最少的依赖项)。

我已经在 Ubuntu 上完成了,但是依赖项列表很糟糕。SDL 引入了 PulseAudio 等。我的下一个猜测是使用 Debian lenny——你认为最好的发行版是什么?

0 投票
3 回答
2614 浏览

java - 改造 void 方法以返回其参数以促进流畅性:破坏性变化?

“API 设计就像性:犯一个错误并在你的余生中支持它” 推特上的乔什·布洛赫

Java 库中有很多设计错误。Stack extends Vector讨论),我们不能在不造成损坏的情况下解决这个问题。我们可以尝试弃用Integer.getInteger讨论),但它可能会永远存在。

尽管如此,可以在不造成损坏的情况下进行某些类型的改造。

Effective Java 第 2 版,第 18 项:优先使用接口而不是抽象类:现有类可以很容易地改造以实现新接口”。

示例:String implements CharSequenceVector implements List等。

Effective Java 第 2 版,第 42 条:明智地使用可变参数:您可以改进现有的方法,该方法将数组作为其最终参数以采用可变参数,而不会对现有客户端产生影响。

一个(不)著名的例子是Arrays.asList,它引起了混乱(讨论),但没有破坏。

这个问题是关于一种不同类型的改造:

你能在void不破坏现有代码的情况下改造一种方法来返回一些东西吗?

我最初的预感是肯定的,因为:

  • 返回类型不影响编译时选择的方法
  • 即使您使用反射,Class.getMethod也无法区分返回类型

但是,我想听听其他在 Java/API 设计方面更有经验的人进行更彻底的分析。


附录:动机

正如标题中所建议的,一个动机是促进流畅的界面风格编程。

考虑这个简单的代码片段,它打印一个打乱的名字列表:

已经Collections.shuffle(List)声明返回输入列表,我们可以这样写:

如果它们要返回输入列表而不是,等,那么使用其他方法Collections会更愉快。事实上,拥有和返回尤其不幸,因为它剥夺了我们编写表达代码的能力,void例如像这样:reverse(List)sort(List)Collections.sortArrays.sortvoid

当然,这种void阻碍流畅性的返回类型不仅限于这些实用方法。这些java.util.BitSet方法也可以编写为返回this(alaStringBufferStringBuilder) 以促进流畅性。

不幸的是,与StringBuilder/不同StringBuffer所有BitSetmutators 都返回void

相关话题

0 投票
2 回答
3161 浏览

xcode - GCC 4.0、4.2 和 LLVM ABI 兼容性

Xcode 支持的三种主要编译器风格(gcc 4.0、4.2 和 llvm)是否相互兼容?在使用最新的 Xcode 工具加速多库项目时,我应该注意哪些问题和极端情况?

0 投票
1 回答
386 浏览

.net - 是否可以在 .NET 库中实现二进制兼容性?

我有一个在 COM 中可见的 .NET 库,它是从 vb6 应用程序调用的。

如果我添加一些方法并发布一个新版本(但不要删除或更改现有方法的签名),我希望能够将它安装在生产机器上,并让它工作。但是,这种方法似乎行不通;我需要重新编译 vb6 应用程序。

有什么办法可以做到这一点?

0 投票
2 回答
433 浏览

gcc - 在旧系统上运行的新 gcc 二进制文件

我有一个用 gcc 4.4.0 编译的二进制文件,并试图在没有 gcc 4.4.0 的旧系统上运行它。它不起作用。错误不是找不到符号,而是无法正确运行并挂起。系统之间的区别是 CentOS 5.5 与 5.2,以及 gcc 4.4.0 与 3.4.6。

在不安装 gcc 4.4.0 的情况下,我该怎么做才能让它在该系统上运行?有没有我们可以放在上面的运行时库?简单地复制依赖项并设置库路径似乎不起作用。

该二进制文件需要 gcc 4.4.0 的功能。

0 投票
1 回答
1295 浏览

com - VB6 IDE 正在锁定已加载项目的 DLL

我负责维护遗留的 VB6 代码,并且遇到了一个关于锁定项目的 COM DLL 的烦人问题。(我们称之为MyProjectMyProject.dll

当我将MyProject加载到 VB6 IDE 中时,我能够编译生成的二进制兼容 DLL MyProject.dll。然后,我可以运行我的(经典 ASP)Web 应用程序,该应用程序与 DLL(或其他任何东西)挂钩。

因此,当我尝试重新编译 COM DLL 时,我收到“权限被拒绝”错误。然后我发现自己必须执行以下步骤才能解锁 DLL:

  1. 检查我没有在其他 VB6 IDE 中打开依赖项目
  2. 回收 IIS
  3. 检查文件不是只读的(有时如果我已将其签入源代码控制)
  4. 关闭项目并重新打开它。

通常它是解决问题的最后一步,并允许我重新编译,这意味着 VB6 IDE 实际上锁定了加载项目的 DLL!

我的同事向我解释说,这与 VB6 项目在 DLL 上具有二进制兼容性的工作方式有关,但无法提出解决方案。

我在其他地方的搜索在答案方面几乎没有产生什么结果。与此相关的搜索查询往往会返回许多不相关的答案(也许我问的是搜索引擎的错误)。

我在 Stackoverflow 上能找到的最接近的东西是几年前的这个问题,但它并不真正符合要求。

有没有人有任何其他建议可以改善这种情况?

0 投票
1 回答
323 浏览

c - avr-gcc 3.4.0 和 avr-gcc 4.3.x 之间的二进制兼容性

我继承了一个链接到可能已经用 gcc3 构建的库的应用程序。或者也许使用 imagecraft 编译器。这些信息现在已经消失在天堂般的位域中,我只剩下一个 libXXX.a 库来链接我的应用程序。我无法重新编译 libXXX.a,因为它需要来自 imagecraft 和其他地方的某些未知头文件,这些头文件在某个时候可能在我的环境中无处不在,但现在无处可寻。

我的问题是,如果我使用 avr-gcc 版本 3.4.0 编译我的应用程序(并链接到那个“特殊”libXXX)会产生一个工作二进制映像,那么期望我可以编译所有其他部分是否合理?我的带有 avr-gcc 4 的应用程序(这个操作有一些非常好的和经过验证的好处),与 libXXX 链接并且仍然可以获得一个工作程序?

从本质上讲,这一切都归结为:avr-gcc 二进制文件是否与“可能是 avr-gcc 3.something 的神秘编译器 X”兼容?

老实说,我已经成功地用 avr-gcc4 编译了我的应用程序的其余部分并将其与库链接,并验证结果有效,但我应该注意什么样的副作用或怪癖?