5

我正在开发一个链接多个静态库的 iOS 应用程序。挑战在于,这些链接库定义了具有不同实现的相同方法名称。奇怪的是,我没有收到任何duplicate symbol definition错误;但是,毫不奇怪,我最终只能访问该方法的一种实现。

更清楚地说,假设我有 libA 和 libB,它们都定义了一个名为 func1() 的全局 C 方法

当我链接 libA 和 libB 并调用 func1() 时,它解析为 libA 或 libB 的实现,而没有任何编译警告。但是,我需要能够分别访问 libA 的 func1() 和 libB 的 func1()。

有一个类似的 SO 帖子解释了如何在 C 中完成它(通过符号重命名),但不幸的是,正如我发现的那样,该objcopy工具不适用于 ARM 架构(因此是 iPhone)。

(我会将它提交到 App Store,因此,动态链接不是一个选项)

4

1 回答 1

4

看来你很幸运 - 你仍然可以用 ARM 二进制格式重命名符号,它只是比objcopy方法更 hacky......

注意:这只是进行了最低限度的测试,我强烈建议您在尝试之前备份所有有问题的库!

另请注意,这仅适用于未使用 C++ 编译器编译的文件!如果在这些文件上使用了 C++ 编译器,这将失败。

  1. 首先,你需要一个像样的十六进制编辑器,在这个例子中,我将使用Hex Fiend
  2. 接下来,您将打开您的库的副本,我们将其命名为lib1-renamed.a,并使用它执行以下操作:

    • 找到您要重命名的符号的名称。可以使用该nm工具找到它,或者,如果您知道标题名称,则应该进行设置。

    • 接下来,您将使用 hex fiend,并以文本替换旧名称(在本例中为foo),并给它一个新名称(在本例中为bar)。这些名称必须具有相同的长度,否则会破坏二进制文件的偏移量!

      注意:如果有多个函数中包含foo's 的名字,你可能会遇到问题。

  3. 现在,您必须编辑您更改的库的标题,以使用新的函数名称 ( bar) 而不是旧的。

如果您正确完成了上述三个简单的†</sup> 步骤,您现在应该能够成功编译和链接这两个文件,并调用这两个实现。

如果您尝试使用通用二进制文件(例如模拟器上的一个)来执行此操作,您最好使用lipo分离两个二进制文件,使用objcopyi386/x64 二进制文件,然后使用我的方法ARM 二进制文件,然后lipo将其重新组合在一起。

†:不保证简单性,也不包括在 Richard J. Ross III 超级保修范围内。有关超级保修的更多信息,请立即致电 1-800-FREE-WARRANTY。现在是 1-800 免费保修!

于 2013-03-11T19:47:31.863 回答