重写静态iOS库中的符号 [英] Rewriting symbols in static iOS libraries

查看:160
本文介绍了重写静态iOS库中的符号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am working on an iOS app which links several static libraries. The challenge is, those linked libraries define same method names with different implementations. Oddly, I don't get any duplicate symbol definition errors; but, to no surprise, I end up with access to only one implementation of the method.

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

To be more clear, say I have libA and libB and they both define a global C method called func1()

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

When I link both libA and libB, and make a call to func1(), it resolves to either libA's or libB's implementation without any compilation warning. I, however, need to be able to access both libA's func1() and libB's func1() separately.

有一个类似的SO帖子解释了如何在C中完成(通过符号)重命名)但不幸的是,正如我发现的那样, objcopy 工具不适用于ARM体系结构(因此是iPhone)。

There's a similar SO post that explains how it can be done in C (via symbol renaming) but unfortunately, as I found out, objcopy tool doesn't work for ARM architecture (hence iPhone).

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

(I will submit it to the App Store, hence, dynamic linking is not an option)

推荐答案

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

It appears that you are in luck - you can still rename symbols with the ARM binary format, it's just a bit more hacky than the objcopy method...

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

NOTE: This has only been tested minimally, and I would strongly advise you to make a backup of all libraries in question before trying this!

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

Also note that this only works for files not compiled with the C++ compiler! This will fail if the C++ compiler was used on these files.


  1. 首先,您将需要一个像样的十六进制编辑,对于这个例子,我将使用 Hex Fiend

  2. 接下来,您将打开您的库的副本,我们称之为 lib1-renamed.a ,并使用它执行以下操作:

  1. First, you will need a decent hex editor, for this example, I will be using Hex Fiend.
  2. Next, you will open up a copy of your of of your libraries, let's call it lib1-renamed.a, and do the following with it:


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

  • Find the name of the symbol you wish to re-name. It can be found using the nm tool, or, if you know the header name, you should be set.

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

Next, you will use hex fiend, and to a textual replace of the old name (in this case foo), and give it a new name (in this case, bar). These names must have the same length, or it will corrupt the binary's offsets!

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

Note: if there is more than one function that contain's foo's name in it, you may have problems.

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

Now, you must edit the headers of the library you changed, to use the new function name (bar) instead of the old one.

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

If you have done the three simple steps above properly, you should now be able to compile & link the two files successfully, and call both implementations.

如果你试图用通用二进制文件(例如一个在模拟器上工作的那个),你,最好使用 lipo 来分离两个二进制文件,在i386 / x64二进制文件上使用 objcopy ,然后在ARM二进制文件上使用我的方法,并将 lipo 一起重新使用。

If you are trying to do this with a universal binary (e.g. one the works on the simulator as well), you'd be best off using lipo to separate the two binaries, using objcopy on the i386/x64 binary, and then using my method on the ARM binary, and lipo it back together.

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

这篇关于重写静态iOS库中的符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆