2010-08-05 15 views
5

Ich muss bei einem Methodenaufruf in einem C++ - Programm interpose (die Klasse befindet sich in einer separaten gemeinsam genutzten Bibliothek). Ich dachte, ich könnte LD_PRELOAD verwenden, aber ich bin mir nicht sicher, wie das funktionieren würde (ich habe nur Beispiele für C-Funktionen gefunden): Gibt es eine Möglichkeit, die Interposition für eine einzelne Methode einzurichten, ohne Code aus der dazwischengeschalteten Klassenimplementierung zu kopieren?LD_PRELOAD für C++ Klassenmethoden

Antwort

2

Es wäre nicht sehr portabel, aber Sie könnten Ihre Interpositionsfunktion in C schreiben und geben Sie den Namen der C++ - Methode. Natürlich müssten Sie diesen Parameter explizit behandeln, aber ich denke, alle ELF-ABIs behandeln es einfach als ein unsichtbares erstes Argument.

+0

Ich habe die gleiche Frage für Sie: Wie rufe ich die ursprüngliche C++ - Methode auf? es scheint, als ob diese Methode ihren Namen verbirgt ... – BruceBerry

+0

'dlsym (RTLD_NEXT," mangled_name_of_function ")'. Übrigens, weder meine Technik noch Tonys werden mit virtuellen Funktionen funktionieren (aber wenn das eine virtuelle Funktion wäre, könntest du sie einfach in einer Unterklasse überschreiben, ne?) – zwol

+0

sollte ich nicht überschreiben, weil ich den Client nicht anfassen soll Code, der das Objekt entweder instanziiert. Die Methode ist nicht virtuell, aber anscheinend funktioniert keine Methode für mich: -/ – BruceBerry

6

Erstellen Sie einfach eine Datei für den dazwischen liegenden Code (stellen Sie sicher, dass die Implementierung nicht in der richtigen Reihenfolge ist) ... die Namespaces, der Klassenname und die Funktion sollten dieselben sein wie für die Methode, die Sie abfangen möchten. Erwähnen Sie in Ihrer Klassendefinition nicht die anderen Methoden, die Sie nicht abfangen möchten. Denken Sie daran, dass LD_PRELOAD einen vollständigen Pfad zum abfangenden gemeinsamen Objekt benötigt.

Zum Beispiel Leere X abfangen :: FN1(), erstellen Sie eine Datei mit libx2.cc:

 
#include <iostream> 

class X 
{ 
    public: 
    void X::fn1(); 
}; 

void X::fn1() { std::cout << "X2::fn()\n"; } 

kompilieren Dann it up:

 
g++ -shared -o libx2.so libx2.cc 

Dann laufen ala

 
LD_PRELOAD=`pwd`/libx2.so ./libx_client 

Prost

+0

das scheint weniger hacky. Ich werde es übrigens versuchen – BruceBerry

+0

, wie rufe ich die ursprüngliche Methode von dieser neuen Methode? – BruceBerry

+0

Huch - nur gerade Ihre Frage bemerkt. Unter Linux (nur) können Sie dlsym (RTLD_NEXT, "name") verwenden - dies besagt explizit, dass die Suchfunktion nicht übereinstimmt und Sie in einem später geladenen Objekt suchen. Für andere Betriebssysteme bin ich mir nicht sicher, aber es müssen einige Webseiten über die Portabilität von Linux sprechen, daher ist eine RTLD_NEXT-Suche eine gute Wahl. Doh - Zack hat vor vielen Jahren alles abgedeckt ...: -. –

Verwandte Themen