在静态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二进制格式重命名符号, objcopy
比objcopy
方法更objcopy
。
注意:这只是最低限度的testing,我强烈build议您在尝试之前对所有有问题的库进行备份 !
另外请注意,这只适用于没有用C ++编译器编译的文件! 如果在这些文件上使用C ++编译器,这将失败。
- 首先,你将需要一个体面的hex编辑器,在这个例子中,我将使用hex恶魔 。
-
接下来,您将打开您的库的一个副本,我们称之为
lib1-renamed.a
,然后执行以下操作:-
find您想要重命名的符号的名称。 可以使用
nm
工具find它,或者,如果您知道标题名称,则应该设置。 -
接下来,你将使用hex的恶魔,并在文本中replace旧名称(在本例中为
foo
),并给它一个新的名字(在这种情况下,bar
)。 这些名称必须具有相同的长度,否则会破坏二进制的偏移量!注意 :如果有多个包含
foo
名字的函数,可能会有问题。
-
-
现在,您必须编辑您更改的库的标题,以使用新的函数名称(
bar
)而不是旧的。
如果你已经完成了上面三个简单的步骤,你现在应该能够成功地编译和链接这两个文件,并调用这两个实现。
如果你想用通用的二进制文件(例如模拟器上的工程文件)来做到这一点,你最好用lipo
来分隔两个二进制文件,在i386 / x64二进制文件上使用objcopy
,然后用我的方法放在ARM二进制文件中,然后将它重新组合起来。
†:简单性不保证,理查德·罗斯三世超级保修也不包括在内。 有关超级保修的更多信息,请立即致电1-800-FREE-WARRANTY。 那现在是1-800-FREE-WARRANTY!