2013-03-05 11 views
12

OK, ich weiß, es gab andere Beiträge darüber, wie Sie Objective-C-Symbole aus einem OS X Binary wirklich nicht entfernen können, weil sie für Obj-C überhaupt funktionieren müssen, aber mein Fall ist ein bisschen anders.Wie man Objective-C-Symbole aus OS X-Binärdateien entfernt?

Ich habe eine einzelne Binärdatei, die ein Bündel ist. Es soll entweder als VST-Plugin oder als AudioUnit-Plugin verwendet werden. Die Idee ist, dass die Binärdatei alle Einstiegspunkte für beide Formate enthält, und Sie kompilieren sie nur einmal, und benennen Sie dann eine Kopie mit ".vst" für die VST-Version und ".component" für die AU-Version . (Dies ist übrigens die JUCE Framework.)

Das Problem ist, dass für die Seite AU, können Sie die Cocoa UI Ansicht zum Erstellen einer Obj-C-Klasse exportieren müssen. Auf der VST-Seite wird diese Klasse niemals verwendet. Aber wenn Sie einen Host wie Ableton Live haben, mit dem Sie sowohl AU- als auch VST-Versionen desselben Plugins gleichzeitig laden können, stoßen wir jetzt auf das typische Obj-C-Namespace-Kollisionsproblem.

Auf der VST Seite, dass bestimmte Klasse Obj-C wird nie gewöhnen. Also möchte ich diese Obj-C-Klassen aus der resultierenden Binärdatei mit "strip" entfernen. Dies hat immer noch den Vorteil, alles nur einmal für beide Formate zu kompilieren.

Wie auch immer, ich habe versucht mit "strip -R stripfile.txt <path to binary>", wo stripfile.txt die Symbole enthält, die ich entfernen möchte, aber es immer fehlschlägt sagen, dass die Symbole nicht in der Binärdatei gefunden werden können. Ich habe versucht, die Namen in der Strip-Datei zu vermischen, aber das hilft nicht (oder mache ich falsch).

Hier sind die entsprechenden Symbole, die ich als Ausgabe von "nm -m" entfernen lassen möchten:

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 

Irgendwelche Ideen?

BTW, ich konnte die fragliche Klasse (mit einem eindeutigen Namen) dynamisch registrieren, was auch das Problem löst. Wenn ich jedoch Strip-Arbeiten ausführen könnte, könnte ich möglicherweise eine Lösung für bereits vorhandene Binärdateien im Feld bereitstellen.

+6

einfach nicht kompilieren und verknüpfen Sie sie in der AU/VST an erster Stelle - richten Sie stattdessen mehrere Ziele. – justin

+1

Ich weiß, dass ich das tun kann, und in der Tat habe ich es bereits über die dynamische Registrierung der fraglichen Klasse funktioniert, was schöner ist, weil es immer noch ermöglicht, alles einmal zu kompilieren und keine separaten Ziele/Binärdateien zu haben - die resultierende Binärdatei immer noch entweder als AU oder VST verwendet werden (dies kann nicht über den "Nicht-Kompilieren-für-VST" -Ansatz getan werden). Ich bin immer noch neugierig, ob es eine Möglichkeit gibt, die Obj-C-Binärdateien von vorhandenen Binärdateien zu entfernen, da dies eine Korrektur für vorhandene Installationen vor Ort ermöglichen würde, bevor mein "besserer" Fix versandbereit ist. – jimw

+0

Das Entfernen der Symbole würde die Klassenstrukturen nicht entfernen, also würde es wahrscheinlich nicht verhindern, dass die Klasse geladen wird (Ich weiß nicht, wie die Laufzeit Klassen findet, aber die Suche nach Symbolen wäre schwieriger, als nur den reservierten Bereich zu betrachten für Klasseninformationen). Sie könnten versuchen, den Namen der Klasse in der Binärdatei zu ändern, aber Sie müssen darauf achten, dass Sie nichts anderes beeinflussen. Ich stimme mit Justin überein, dass das Kompilieren zweimal die beste Wahl ist, da es einfacher ist als dynamische Registrierung. – ughoavgfhw

Antwort

3

Sie können nicht einfach eine Klasse aus einer Binärdatei entfernen. Was Sie jedoch tun können, ist, die Objective-C-Laufzeit zu glauben, dass Ihr Plugin keinen Objective-C-Code enthält. Ändern Sie einfach __objc_imageinfo in __objc_imageinfX zum Beispiel in Ihrer VST-Plugin-Binärdatei. Sie können es leicht mit Perl:

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

Nach der VST-Plugin Patchen all Objective-C Initialisierung umgangen werden, und Sie werden diese Fehlermeldung nicht sehen: Class JuceDemoProjectAU is implemented in both …/VSTPlugin and …/AUPlugin. One of the two will be used. Which one is undefined.

Vorsicht, Sie sollten wirklich benutze diesen Trick nicht! Die geeignete Lösung für Ihr Problem besteht entweder darin, zwei verschiedene Versionen Ihres Plugins zu kompilieren oder Klassen dynamisch zu registrieren, wie von anderen vorgeschlagen.

+0

Aus irgendeinem Grund konnte ich dies auch nicht ausführen, die Objective-C-Symbole bleiben auch nach Ausführung des Befehls im Binärcode. Gute Idee, im Prinzip. – Perception

+0

Ich habe vergessen zu erwähnen, dass dies 64-Bit-Plugins voraussetzt. Bei 32-Bit-Plug-ins sollten Sie stattdessen "__image_info" in "__image_infX" ändern. – 0xced