【问题标题】:Can adding a static variable break binary compatibility on Linux?添加静态变量会破坏 Linux 上的二进制兼容性吗?
【发布时间】:2016-08-20 18:45:02
【问题描述】:

我对 linux 平台上的共享库进行了一些更改,并将更新后的库发送给最终用户。最终用户报告说他们认为二进制兼容性已被破坏(不确定他们是如何知道的)。

我所做的更改是针对内部类(用户没有头文件):

我做了 3 种不同的更改:

  1. 为类添加了受保护的静态成员变量(实际上并不需要保护)
  2. 为类添加了一个私有静态成员
  3. 将静态变量添加到 cpp 文件(在非匿名命名空间中)

这些更改中的哪些(如果有)会破坏二进制兼容性,我应该如何添加静态变量以免破坏二进制兼容性?或者添加一个静态变量通常可以安全地保持二进制兼容性?

我所做的更改示例(以+ 表示)

内部 .h 文件:

class A
{
protected:
    + static Mutex m;
}

内部cpp文件

void A::doSomething
{
    + m.Lock();
    ...
    + m.Unlock();
}

【问题讨论】:

  • 你到底在问什么?添加静态变量通常不会破坏二进制兼容性。还有 mutex 与它有什么关系?您是在询问从共享库推断出的线程安全单例吗?
  • 最终用户断言的不兼容的性质是什么?如果他们没有收到标头,则它不能涉及他们直接针对库编写的任何代码。
  • 用户说他们认为他们必须重新编译才能使库工作,但他们目前不能这样做,因为编译需要几个小时。所以我的问题是“我做了什么改变来破坏二进制兼容性”和“我怎样才能将静态变量添加到共享库中而无需用户重新编译他们的代码”
  • 如果您的库二进制文件具有不同的 SO 版本,则最终用户需要重新链接。这与库中的任何特定更改没有直接关系。
  • static 类内的成员变量具有外部链接,因此它们在二进制文件中可见static 类外的变量具有内部链接(必须喜欢 C++),因此它们在库外是不可见的。但既不会改变对象的大小或布局,也不会改变任何函数签名。从 API 的角度来看,旧代码应该与仅以您描述的方式更改的新动态库二进制兼容。

标签: c++ linux shared-libraries binary-compatibility


【解决方案1】:

“二进制兼容性”可能与保存/加载或网络数据包有关。 或者他们可能有编译问题 - 在这种情况下,可能是您使用不同的编译器/编译器版本构建它。

还要考虑结构包值。您可以使用不同的结构包设置具有不同的相同结构大小。

【讨论】:

  • 是的,我相信这里的答案有些混乱。我说的是“两个硬件/软件系统无需重新编译即可运行相同的二进制代码的能力。”
【解决方案2】:

所以我猜这个问题更笼统,比如“添加静态变量会导致二进制兼容性问题,如果是,你如何避免这个问题?”

当然这可能会导致问题。

最终用户可能会做许多不受支持的事情,从将库的大小硬编码到他的程序中,到占用您的内存,再到将错误数据传递给您的库,以便 执行在用户的内存等上。

不过,这些都与二进制兼容性无关。

您需要让最终用户解释他们所看到的确切。这说起来容易做起来难,因为最终用户可能在您和实际观察故障的人之间有一个“电话坏了”。但它必须发生,否则你永远不会取得进展。

【讨论】:

    猜你喜欢
    • 2013-03-08
    • 2018-12-27
    • 2012-09-24
    • 1970-01-01
    • 2015-07-06
    • 1970-01-01
    • 2014-07-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多