我正在开发一个连接多个静态库的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,因此,动态链接不是一种选择)
答案 0 :(得分:3)
看起来你很幸运 - 你仍然可以用ARM二进制格式重命名符号,它比objcopy
方法更加简单......
注意:这只是经过最低限度的测试,我强烈建议您在尝试之前备份所有相关库!
另请注意,这仅适用于未使用C ++编译器编译的文件!如果在这些文件上使用C ++编译器,则将失败。
接下来,您将打开您的图书馆的副本,我们称之为lib1-renamed.a
,并使用它执行以下操作:
找到您要重命名的符号的名称。可以使用nm
工具找到它,或者,如果您知道标题名称,则应该设置它。
接下来,您将使用十六进制恶魔,并使用文本替换旧名称(在本例中为foo
),并为其指定一个新名称(在本例中为bar
)。这些名称必须具有相同的长度,否则会损坏二进制文件的偏移量!
注意:如果有多个函数包含foo
的名称,则可能会出现问题。
现在,您必须编辑您更改的库的标题,以使用新函数名称(bar
)而不是旧函数名称。
如果您已正确完成上述三个简单的†步骤,那么您现在应该可以编译&成功链接这两个文件,并调用两个实现。
如果您尝试使用通用二进制文件(例如,也可以在模拟器上运行),您最好使用lipo
分隔两个二进制文件,使用objcopy
在i386 / x64二进制文件上,然后在ARM二进制文件上使用我的方法,并将lipo
重新组合在一起。
†:不保证简单,理查德J.罗斯三世超级保修也不包括。有关超级保修的更多信息,请立即致电1-800-FREE-WARRANTY。现在是1-800免费保修!