重写静态 iOS 库中的符号

Ege*_*nar 5 xcode static-linking ios

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

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

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

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

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

Ric*_*III 4

看来你很幸运 - 你仍然可以使用 ARM 二进制格式重命名符号,它只是比该objcopy方法更hacky一点......

\n\n

注意:这仅经过了最低限度的测试,我强烈建议您在尝试此操作之前备份所有有问题的库!

\n\n

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

\n\n
    \n
  1. 首先,您需要一个像样的十六进制编辑器,在这个例子中,我将使用Hex Fiend
  2. \n
  3. 接下来,您将打开您的库的副本,我们将其命名为lib1-renamed.a,并对其执行以下操作:

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

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

      \n\n

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

    • \n
  4. \n
  5. 现在,您必须编辑更改的库的标头,以使用新函数名称 ( bar) 而不是旧函数名称。

  6. \n
\n\n

如果您正确完成了上面三个简单的\xe2\x80\xa0步骤,您现在应该能够成功编译和链接这两个文件,并调用这两个实现。

\n\n

如果您尝试使用通用二进制文件(例如,也可以在模拟器上运行的二进制文件)来执行此操作,那么您最好使用lipo分离两个二进制文件,objcopy在 i386/x64 二进制文件上使用,然后使用我的方法在 ARM 二进制文件上,以及lipo将其重新组合在一起。

\n\n

\xe2\x80\xa0:不保证简单性,也不在 Richard J. Ross III 超级保修范围内。有关超级保修的更多信息,请立即致电 1-800-FREE-WARRANTY。现在是 1-800 免费保修!

\n

  • @AndiDog 我很欣赏你的编辑,但我的幽默感会一直存在。有时人们过于认真地对待这个网站,开怀大笑会让您心情愉快。 (7认同)