使用GNU链接器包装C++函数

Mik*_*ike 7 c++ linker mocking

我喜欢GNU链接器功能来包装很多函数.我通常使用它来模拟例如rand()之类的非确定性函数调用.考虑以下示例,我想为giveMeanumber编写单元测试:

//number.cpp
int giveMeANumber() {
  return rand() % 6 + 1;
}
Run Code Online (Sandbox Code Playgroud)

我可以使用GNU链接器功能包装来调用rand,如下所示:

//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
Run Code Online (Sandbox Code Playgroud)

有没有办法对普通的C++函数做同样的事情?以下不起作用,我想这是因为名称错误.但即使我用错误的名字尝试它也不起作用.

//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
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

smp*_*kes 9

您还extern "C"需要要包装的函数(如果可能)或者您需要包装受损的名称,例如,__wrap__Z3foov然后传递--wrap=_Z3foov给链接器.

获得正确的下划线有点棘手.这对我有用:

$ 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
Run Code Online (Sandbox Code Playgroud)