简体   繁体   中英

Wrapping C++ functions with GNU linker

I like the GNU linker functionality to wrap functions a lot. I normally use it mock eg nondeterministic function calls like rand() . Consider the following example where I would like to write a unit test for giveMeANumber :

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

I can wrap the call to rand with the GNU linker functionality wrap like this:

//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

Is there any way to do the same with normal C++ functions? The following does not work, I guess it is because of name mangling. But even when I try it with the mangled name it does not work.

//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

You need to either also extern "C" the function you want to wrap (if that's possible) or you need to wrap the mangled name, eg, __wrap__Z3foov and then pass --wrap=_Z3foov to the linker.

Getting the underscores right is a little tricky. This works for 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

It seems like you are trying to mock functions and classes for testing. Have you consider using Google Mock

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM