如何从OS X二进制文件中去除Objective-C符号?

12

好的,我知道有其他帖子提到过无法从OS X二进制文件中删除Objective-C符号,因为它们对Obj-C的工作是必要的,但我的情况有点不同。

我有一个单独的二进制文件,它是一个捆绑包。它旨在用作VST插件或AudioUnit插件。想法是二进制文件包含两种格式的所有入口点,您只需编译一次,然后将一个副本命名为".vst"以获取VST版本,".component"以获取AU版本。 (顺便说一句,这是使用JUCE框架实现的。)

问题是,在AU方面,您必须导出一个Obj-C类来创建Cocoa UI视图。在VST方面,此类永远不会被使用。但是,如果您像Ableton Live这样的主机允许同时加载相同插件的AU和VST版本,那么我们现在遇到了典型的Obj-C命名空间冲突问题。

在VST方面,那个特定的Obj-C类永远不会被使用。因此,我想使用“strip”从生成的二进制文件中剥离这些Obj-C类。这仍然保持了只编译一次以适用于两种格式的优势。
无论如何,我尝试使用“strip -R stripfile.txt ”,其中stripfile.txt包含我想要剥离的符号,但它总是失败,并说找不到二进制文件中的符号。我尝试过在strip文件中更改名称,但那并没有帮助(或者我做错了)。
这里是我想要剥离的相关符号,由“nm -m”输出:
000000000003bb00 (__TEXT,__text) non-external -[JuceDemoProjectAU description]
000000000003bb60 (__TEXT,__text) non-external -[JuceDemoProjectAU interfaceVersion]
000000000003ba00 (__TEXT,__text) non-external -[JuceDemoProjectAU uiViewForAudioUnit:withSize:]
0000000000b02398 (__DATA,__objc_data) external _OBJC_CLASS_$_JuceDemoProjectAU
0000000000b023c0 (__DATA,__objc_data) external _OBJC_METACLASS_$_JuceDemoProjectAU

任何想法吗?
顺便说一下,我后来成功地能够动态注册相关类(使用唯一名称),这也解决了问题。但是,如果我能让strip工作,我有可能为已经存在于现场的二进制文件部署一个解决方案。

6
不要在一开始就编译和链接AU/VST插件,而是设置多个目标。 - justin
1
我知道我可以做到这一点,事实上,正如我所提到的,我已经通过动态注册相关类来使其工作,这更好,因为它仍然允许编译所有内容而不需要单独的目标/二进制文件-生成的二进制文件仍然可以用作AU或VST(无法通过不为VST编译它的方法实现)。我仍然很好奇是否有任何方法可以从现有的二进制文件中剥离Obj-C二进制文件,因为这将允许在我的“更好”的修复准备好发布之前修复现有的现场安装问题。 - jimw
删除符号并不会删除类结构,所以它可能不会阻止类的加载(我不知道运行时如何找到类,但搜索符号比仅查看保留给类信息的部分要困难得多)。您可以尝试更改二进制文件中的类名称,但必须小心,以确保不会影响其他任何内容。我同意Justin的建议,编译两次是最好的选择,因为比动态注册更容易实现。 - ughoavgfhw
2个回答

3

不能仅仅从二进制文件中删除一个类。但是你可以欺骗Objective-C运行时,使其认为你的插件不包含任何Objective-C代码。例如,在你的VST插件二进制文件中将__objc_imageinfo更改为__objc_imageinfX即可。你可以使用perl轻松完成此操作:

perl -pi -e 's/__objc_imageinfo/__objc_imageinfX/g' <path to binary>

在修补VST插件后,所有的Objective-C初始化都将被绕过,你将不会再看到这个错误信息:Class JuceDemoProjectAU is implemented in both …/VSTPlugin and …/AUPlugin. One of the two will be used. Which one is undefined.。请注意,您真的不应该使用这个技巧!解决您的问题的适当方法是编译两个不同版本的插件或像其他人建议的那样动态注册类。

由于某些原因,我无法使其工作,即使在执行命令后,Objective C符号仍然存在于二进制文件中。不过,从原理上讲,这是一个好主意。 - Perception
我忘了提到这假设是64位插件。对于32位插件,您可能需要将__image_info更改为__image_infX - 0xced

2
去年在coreaudio-list上有一个关于类似问题的线程:Cocoa类与AU和VST插件之间的冲突
提供的解决方案是动态注册类,这正是您已经成功实现的。如果有一种方法可以像您想要的那样剥离符号,我相信这些人会知道的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接