2010-08-05 9 views
5

Necesito interponerme en una llamada a un método en un programa C++ (la clase reside en una biblioteca compartida separada). Pensé que podría usar LD_PRELOAD, pero no estoy seguro de cómo funcionaría (solo encontré ejemplos de funciones C): ¿hay alguna manera de configurar la interposición para un único método sin copiar sobre ningún código de la implementación de clase interpuesta?LD_PRELOAD para métodos de clase C++

Respuesta

2

No sería muy portátil, pero podría escribir su función de interposición en C y darle el nombre mutilado del método C++. Tendría que manejar este parámetro explícitamente, por supuesto, pero creo que todos los ABI de ELF solo lo tratan como un primer argumento invisible.

+0

tengo la misma pregunta para usted: ¿Cómo llamo al método original de C++? parece que este método oculta su nombre ... – BruceBerry

+0

'dlsym (RTLD_NEXT," mangled_name_of_function ")'. Por cierto, ni mi técnica ni la de Tony funcionarán con funciones virtuales (pero si esta fuera una función virtual, podrías anularla en una subclase, ¿no?) – zwol

+0

No debería anularla porque no debería tocar al cliente código que ejemplifica el objeto tampoco. El método no es virtual, pero aparentemente ninguno de los métodos me funciona: -/ – BruceBerry

6

Simplemente cree un archivo para el código interpuesto (asegurándose de que la implementación esté fuera de línea) ... los espacios de nombres, el nombre de clase y la función deberían ser los mismos que para el método que desea interceptar. En su definición de clase, no mencione los otros métodos que no desea interceptar. Recuerde que LD_PRELOAD necesita una ruta completa al objeto compartido de interceptación.

Por ejemplo, para interceptar vacío X :: na1(), cree un archivo con libx2.cc:

 
#include <iostream> 

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

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

A continuación, compile arriba:

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

A continuación, ejecute ala

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

Cheers

+0

esto parece menos hacky. Lo intentaré – BruceBerry

+0

por cierto, ¿cómo llamo al método original desde este nuevo método? – BruceBerry

+0

Yikes: acabo de notar su pregunta. En Linux (solo), puede usar dlsym (RTLD_NEXT, "nombre"): esto indica explícitamente que no coincide con la función de búsqueda, y encuentra uno en un objeto cargado más adelante. Para otros sistemas operativos, no estoy seguro, pero tiene que haber algunas páginas web que hablan sobre la portabilidad de Linux, por lo que una búsqueda RTLD_NEXT es una buena apuesta. Doh - Zack cubrió todos los agradecimientos hace años ...: -. –

Cuestiones relacionadas