重写静态iOS库中的符号

时间:2013-03-11 18:06:58

标签: ios xcode static-linking

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

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

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

There's a similar SO post解释了如何在C中完成(通过符号重命名),但不幸的是,正如我发现的那样,objcopy工具不适用于ARM体系结构(因此是iPhone)。

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

1 个答案:

答案 0 :(得分:3)

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

注意:这只是经过最低限度的测试,我强烈建议您在尝试之前备份所有相关库!

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

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

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

    • 接下来,您将使用十六进制恶魔,并使用文本替换旧名称(在本例中为foo),并为其指定一个新名称(在本例中为bar )。这些名称​​必须具有相同的长度,否则会损坏二进制文件的偏移量!

      注意:如果有多个函数包含foo的名称,则可能会出现问题。

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

  4. 如果您已正确完成上述三个简单的步骤,那么您现在应该可以编译&成功链接这两个文件,并调用两个实现。

    如果您尝试使用通用二进制文件(例如,也可以在模拟器上运行),您最好使用lipo分隔两个二进制文件,使用objcopy在i386 / x64二进制文件上,然后在ARM二进制文件上使用我的方法,并将lipo重新组合在一起。

    †:不保证简单,理查德J.罗斯三世超级保修也不包括。有关超级保修的更多信息,请立即致电1-800-FREE-WARRANTY。现在是1-800免费保修!