如何防止全局覆盖的“新”运算符从外部库链接

时间:2009-12-10 08:16:31

标签: c++ iphone xcode linker new-operator

在我们的iPhone XCode 3.2.1项目中,我们将链接到2个外部静态C ++库libBlue.a和libGreen.a。 libBlue.a全局覆盖“ new ”运算符,用于它自己的内存管理。然而,当我们构建项目时,libGreen.a最终使用libBlue的 new 运算符,这会导致崩溃(可能是因为libBlue.a正在对所分配的结构类型做出假设)。 libBlue.a和libGreen.a都是由第三方提供的,因此我们无法更改任何源代码或构建选项。

当我们从项目中删除libBlue.a时,libGreen.a没有任何问题。然而,没有任何数量的库的链接顺序混洗似乎解决了问题,也没有任何实验与各种链接标志。有没有办法让XCode告诉链接器“让libGreen使用 new 运算符使用标准C ++ new 运算符而不是libBlue重新定义的运算符”?< / p>

5 个答案:

答案 0 :(得分:2)

也许您可以使用GNU objcopy进行调查,这与objcopy --redefine-sym oldNew=newNew libBlue.a一致。我看到的最大问题是Apple的开发人员工具套件似乎不包括objcopy。您可以从MacPortssudo port install binutils)安装objcopy,但该objcopy可能无法操作ARM对象文件。 MacPorts中有几个ARM binutils,我猜你arm-elf-binutils是最好的选择。

除此之外,你可以反汇编libBlue.a,用sed脚本重命名它的新运算符,然后重新组装它。也许你甚至可以直接操作libBlue.a符号表。

答案 1 :(得分:1)

我不确定这是否可行,但您可以尝试在代码中本地覆盖 new 。在您的实现中,您可以复制/粘贴标准 new 运算符的实现。当您需要在代码中创建 new 对象时,请调用 new 而不是libBlue覆盖的全局 new 。然后找到libBlue的作者并给他一点思路。

查看http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=40以获得比我希望提供的更好的摘要。

编辑:你的意思是libGreen.a中的代码会从libBlue调用 new ,或者你的意思是你的代码创建了一个“ new ClassDefinedInLibGreen(...) “并最终使用libBlue的 new 运算符?我发布的解决方案(如果它甚至可以工作)只适用于后一种情况,因为您无法访问任何第三方库的源来控制运算符覆盖。

答案 2 :(得分:0)

您可以在单独的进程中隔离libBlue.a和libGreen.a,从而有效地创建一个服务器,该服务器允许通过某种形式的进程间通信访问封装的功能。这显然具有性能影响,但解决了全局命名空间污染问题。

答案 3 :(得分:0)

可能存在非技术性解决方案:

  1. 可以提取libBlue为单独的应用程序提供的功能。
  2. 您可以联系libBlue的支持。其他人也可能有这个问题。
  3. 寻找替代方案。
  4. P.S。奇怪的是,如果开发人员如果libBlue做了一些“聪明”的事情,却不了解如何解决他们引入的问题。

答案 4 :(得分:0)

库的二进制编辑?如果要信任互联网,则它位于Mach-O format。有关详细信息,请参阅this reference

libBlue.a必须包含导出符号的列表。尝试将其“新”重命名为“neo”或其他内容。 libBlue应该仍然是内部一致的,但是libGreen现在只能在链接时找到系统“new”。

或者,libGreen.a必须包含一个未解决的符号列表,包括“新”,可能在__DATA,__la_symbol_ptr部分。您可以使用应用程序中定义的执行相同工作的包装函数的名称替换“new”的实例。 (甚至可能直接调用new,但最终可能会回到libBlue中。)