2013-03-11 84 views
2

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

更清楚,说我有力霸和libB,他们都定义一个全局的C法称为FUNC1()

当我链接都力霸和libB,做出FUNC1(通话),它解析到libA或libB的实现,没有任何编译警告。但是,我需要能够分别访问libA的func1()和libB的func1()。

There's a similar SO post,解释它如何可以在C完成(通过符号重命名),但不幸的是,我发现,objcopy工具不会对ARM架构(因此iPhone)工作。

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

+0

如果你有任何库的源代码,那么解决方案是显而易见的。或者,你可以使用'lipo'将两个库打包成一个,如果我的内存不足,应该只保留其中一个符号。 – 2013-03-11 18:09:36

+0

谢谢@ RichardJ.RossIII,但我没有源代码,不确定你的建议会有帮助,因为我想分开保存这些符号,我需要它们两个,我不想将它们还原为一个符号 – 2013-03-11 19:19:02

+0

我会比如说使用'dlopen'和'dlsym'动态地分别加载符号,但不幸的是,现在苹果禁止使用这些符号,这将不起作用。我不是''.a'文件结构的专家,但我有一种感觉,可以通过十六进制编辑器手动执行此操作。让我尝试一下,我会看看我能否帮助你。 – 2013-03-11 19:24:37

回答

2

看来,你是幸运的 - 你仍然可以使用ARM二进制格式命名的符号,它只是有点更哈克比objcopy方法...

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

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

  1. 首先,您将需要一个体面的十六进制编辑器,在这个例子中,我将使用Hex Fiend
  2. 接下来,你会打开你的库的副本,让我们称之为lib1-renamed.a,并用它做了以下内容:

    • 查找符号的你希望的名字重新命名。可以使用nm工具找到它,或者,如果您知道标题名称,则应该设置它。接下来,您将使用十六进制恶魔,并对旧名称进行文本替换(在本例中为foo),并为其指定一个新名称(在此例中为bar)。这些名字必须具有相同的长度,否则会破坏二进制的偏移量!

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

  3. ,你必须编辑你改变了图书馆的头,使用新的函数名(bar),而不是旧的。

如果你已经完成了三个简单的以上步骤正确,你现在应该能够成功编译&链接的两个文件,并呼吁双方实现。

如果你想用一个通用二进制做到这一点(例如,一个仿真器上的作品也一样),你最好关闭使用lipo两个二进制文件分开,使用了i386/X64二进制objcopy,然后在ARM二进制上使用我的方法,并将其与lipo重新组合。

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

+0

明天测试这个第一件事,非常感谢你的努力(和你的脚注更多!):) – 2013-03-11 20:48:40

+1

@EgeAkpinar不要忘记你的免费超级保证! – 2013-03-11 20:51:20

+0

事实证明,我不需要保修,因为它像一个魅力。我曾尝试重命名,但错过了我应该重新命名为相同的长度。非常感谢! – 2013-03-12 10:18:06