在静态iOS库中重写符号

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

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

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

有一个类似的SOpost ,解释如何在C(通过符号重命名),但不幸的是,因为我发现, objcopy工具不适用于ARM体系结构(因此iPhone)。

(我将把它提交给App Store,因此,dynamic链接不是一个选项)

看起来你很幸运 – 你仍然可以用ARM二进制格式重命名符号, objcopyobjcopy方法更objcopy

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

另外请注意,这只适用于没有用C ++编译器编译的文件! 如果在这些文件上使用C ++编译器,这失败。

  1. 首先,你将需要一个体面的hex编辑器,在这个例子中,我将使用hex恶魔 。
  2. 接下来,您将打开您的库的一个副本,我们称之为lib1-renamed.a ,然后执行以下操作:

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

    • 接下来,你将使用hex的恶魔,并在文本中replace旧名称(在本例中为foo ),并给它一个新的名字(在这种情况下, bar )。 这些名称必须具有相同的长度,否则会破坏二进制的偏移量!

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

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

如果你已经完成了上面三个简单的步骤,你现在应该能够成功地编译和链接这两个文件,并调用这两个实现。

如果你想用通用的二进制文件(例如模拟器上的工程文件)来做到这一点,你最好用lipo来分隔两个二进制文件,在i386 / x64二进制文件上使用objcopy ,然后用我的方法放在ARM二进制文件中,然后将它重新组合起来。

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