2011-12-06 12 views
6

Mi piace la funzionalità del linker GNU per avvolgere molto le funzioni. Normalmente lo uso simulato ad es. chiamate non deterministiche chiamate come rand(). Si consideri il seguente esempio in cui mi piacerebbe scrivere un test unità per giveMeANumber:Wrapping delle funzioni C++ con il linker GNU

//number.cpp 
int giveMeANumber() { 
    return rand() % 6 + 1; 
} 

posso avvolgere la chiamata a rand con la GNU involucro funzionalità linker in questo modo:

//test.cpp 
extern "C" int __wrap_rand(void) { 
return 4; 
} 

void unitTest() { 
    assert giveMeANumber() == 5; 
} 

$ g++ test.cpp -o test number.o -Xlinker --wrap=rand 

C'è un modo fare lo stesso con le normali funzioni C++? Quello che segue non funziona, immagino sia a causa del nome di mangling. Ma anche quando provo con il nome storpiato non funziona.

//number.cpp 
int foo() { 
    //some complex calculations I would like to mock 
} 
int giveMeANumber() { 
    return foo() % 6 + 1; 
} 

//test.cpp 
extern "C" int __wrap_foo(void) { 
return 4; 
} 

$ g++ test.cpp -o test number.o -Xlinker --wrap=foo 

Qualche idea?

+0

In realtà, rand è una funzione deterministica. Restituisce una sequenza numerica pseudo-casuale. Chiama il rand restituirà la stessa sequenza di numeri per ogni seme specificato utilizzato con srand. – TJD

+1

Ok, bravo, è vero. Ma per mantenere l'esempio breve e leggibile, non ho usato un seme. – Mike

+0

È necessario rinominare '__wrap_foo' in' getRandomNumber'. (http://xkcd.com/221/) –

risposta

8

è necessario o anche extern "C" la funzione che si desidera avvolgere (se è possibile) o è necessario avvolgere il nome storpiato, per esempio, __wrap__Z3foov e poi passare --wrap=_Z3foov al linker.

Ottenere i caratteri di sottolineatura corretti è un po 'complicato. Questo funziona per me:

$ cat x.cc 
#include <iostream> 
using namespace std; 

int giveMeANumber(); 

int main() { 
    cerr << giveMeANumber() << endl; 
    return 0; 
} 

$ cat y.cc 
int giveMeANumber() { 
    return 0; 
} 

extern "C" int __wrap__Z13giveMeANumberv() { 
    return 10; 
} 

$ g++ -c x.cc y.cc && g++ x.o y.o -Wl,--wrap=_Z13giveMeANumberv && ./a.out 
10 
+0

C collegamento per la funzione da avvolgere C++ non è un'opzione perché questa funzione potrebbe essere sovraccaricata e dovrebbe essere ancora possibile chiamarla da altre funzioni C++. Ho provato a racchiudere il nome storpiato, ma non funziona. Quello che ho fatto è questo: 'extern" C "int __wrap__Z3foov (void) { \t return 4; } void thisIsATest() { assert 5 == giveMeANumber(); } 'insieme all'opzione linker' -Xlinker --wrap = _Z3foov'. Sfortunatamente, la vera funzione 'pippo' viene ancora chiamata. Qualche idea? – Mike

+0

Ho aggiunto un esempio. Mi ci è voluto un po 'per ottenere tutti i caratteri di sottolineatura corretti. – smparkes

+0

E grazie per la domanda. Non sapevo nemmeno di --wrap. Molto bella. – smparkes

1

Sembra che si stia provando a simulare funzioni e classi per il test. Hai considerare l'utilizzo di Google Mock

+1

L'utilizzo di Google mock non è un'opzione per me. Voglio realizzare questo solo con l'aiuto del linker GNU. – Mike

Problemi correlati