Wie kann verhindert werden, dass ein global überschriebener "new" -Operator von einer externen Bibliothek eingebunden wird?

8

In unserem iPhone XCode 3.2.1-Projekt verknüpfen wir zwei externe statische C ++ - Bibliotheken, libBlue.a und libGreen.a. libBlue.a überschreibt global den Operator " new " für seine eigene Speicherverwaltung. Wenn wir jedoch unser Projekt erstellen, wird libGreen.a mit dem Operator new von libBlue beendet, was zu einem Absturz führt (vermutlich, weil libBlue.a Annahmen über die Art der zugewiesenen Strukturen trifft). Sowohl libBlue.a als auch libGreen.a werden von Drittanbietern zur Verfügung gestellt, so dass wir weder ihren Quellcode noch ihre Build-Optionen ändern können.

Wenn wir libBlue.a aus dem Projekt entfernen, hat libGreen.a keine Probleme. Es scheint jedoch, dass kein Mischen der Verknüpfungsreihenfolge der Bibliotheken das Problem behebt, und auch keine Experimente mit den verschiedenen Verknüpfungsflags. Gibt es eine Möglichkeit, XCode mitzuteilen, dass der Linker "libGreens Verwendung des neuen Operators mit dem standardmäßigen C ++ neuen Operator statt dem von libBlue neu definierten"?

    
Marc Prud'hommeaux 10.12.2009, 08:16
quelle

5 Antworten

2

Vielleicht könntest du mit GNU objcopy etwas in der Art von objcopy --redefine-sym oldNew=newNew libBlue.a untersuchen. Das größte Problem, das ich dabei sehe, ist, dass die Developer Tool Suite von Apple scheinbar kein objcopy enthält. Sie können objcopy von MacPorts ( sudo port install binutils ) installieren, aber dieses objcopy kann ARM-Objektdateien wahrscheinlich nicht manipulieren. Es gibt ein paar ARM-Binutils in MacPorts, und ich denke, arm-elf-binutils ist deine beste Wette.

Abgesehen davon könnten Sie libBlue.a möglicherweise disassemblieren, seinen neuen Operator mit einem sed -Skript umbenennen und ihn dann wieder zusammensetzen. Vielleicht könnten Sie sogar die libBlue.a-Symboltabelle direkt manipulieren.

    
mrkj 23.12.2009, 04:01
quelle
1

Ich bin nicht sicher, ob das funktioniert, aber Sie können versuchen, lokal neu in Ihrem Code zu überschreiben. In Ihrer Implementierung können Sie die Implementierung des Standardoperators new kopieren / einfügen. Wenn Sie in Ihrem Code ein neues Objekt erstellen müssen, rufen Sie Ihr neues anstelle des globalen neuen auf, das libBlue überschrieben hat. Dann finden Sie den Autor von libBlue und geben Sie ihm ein Stück Ihrer Meinung.

Sehen Sie sich Ссылка für eine bessere Zusammenfassung an, als ich hoffen kann .

Edit: Meinst du, dass der Code innerhalb von libGreen.a new von libBlue aufruft, oder meinst du, dein Code erzeugt ein neues ClassDefinedInLibGreen (...) "und endet mit libBlue neuen Operator? Die Lösung, die ich gepostet habe (wenn sie überhaupt funktioniert), würde nur für den letzteren Fall funktionieren, da Sie keinen Zugriff auf die Quelle für die Bibliothek eines Drittanbieters haben, um die Operatorüberschreibungen zu steuern.

    
psublue 10.12.2009 16:36
quelle
0

Sie können libBlue.a und libGreen.a in einem separaten Prozess isolieren, wodurch effektiv ein Server erstellt wird, der den Zugriff auf die gekapselte Funktionalität über eine Art von Interprozesskommunikation ermöglicht. Dies hat eindeutig Auswirkungen auf die Leistung, löst aber das Problem des globalen Namensraumverschmutzung.

    
William Bell 10.12.2009 17:15
quelle
0

Es kann nicht-technische Lösungen geben:

  1. Es ist möglich, die Funktionalität zu extrahieren, die libBlue zur Verfügung stellt, um die Anwendung zu trennen.
  2. Sie können den Support von libBlue kontaktieren. Andere Leute könnten auch das Problem haben.
  3. Finde eine Alternative.

P.S. Es ist seltsam, wenn Entwickler, wenn libBlue etwas "kluges" Ding gemacht haben, ohne zu verstehen, wie man Problem löst, das sie eingeführt haben.

    
Konstantin Tenzin 10.12.2009 17:15
quelle
0

Binärbearbeitung der Bibliotheken? Wenn dem Interweb vertraut werden soll, befindet es sich im Mach-O-Format . Einzelheiten hierzu finden Sie in dieser Referenz .

libBlue.a muss eine Liste exportierter Symbole enthalten. Versuchen Sie, sein "neues" zu "neo" oder etwas umzubenennen. libBlue sollte immer noch intern konsistent sein, aber libGreen findet das System beim Verknüpfen nur noch "neu".

Alternativ dazu muss libGreen.a eine Liste nicht aufgelöster Symbole enthalten, einschließlich "new", wahrscheinlich in einem __DATA,__la_symbol_ptr -Abschnitt. Sie können die Instanzen von "new" durch den Namen einer Wrapper-Funktion ersetzen, die in Ihrer App definiert ist und die gleiche Arbeit ausführt. (vielleicht sogar direkt neu anrufend, aber das könnte in libBlue enden.)

    
AShelly 23.12.2009 22:02
quelle