我在网上search了很多,但我找不到一个与g ++一起工作的例子,所有的例子都使用gcc。 我不断收到的错误是
wrap_malloc.o: In function `__wrap_malloc(unsigned int)': wrap_malloc.cc:(.text+0x20): undefined reference to `__real_malloc(unsigned int)' wrap_malloc.o: In function `main': wrap_malloc.cc:(.text+0x37): undefined reference to `__wrap_malloc' collect2: ld returned 1 exit status
创build这个错误的代码如下(如果我使用gcc进行编译并将头文件从cstdio更改为stdio.h,则此代码有效):
#include <cstdio> #include <cstdlib> void *__real_malloc(size_t); void *__wrap_malloc(size_t c) { printf("My malloc called with %d\n", c); return __real_malloc(c); } int main(void) { void *ptr = malloc(12); free(ptr); return 0; }
这是我如何编译它:
wrap_malloc.o: wrap_malloc.cc g++ -c wrap_malloc.cc -o wrap_malloc.o wrap_malloc: wrap_malloc.o g++ wrap_malloc.o -o wrap_malloc -Wl,--wrap,malloc
谢谢!
当您使用C ++编译器时,所有名称都会被损坏。 当你运行nm wrap_malloc.o
,这意味着什么变得清晰,它应该给你这样的东西:
00000000 b .bss 00000000 d .data 00000000 r .rdata 00000000 t .text U __Z13__real_mallocj 00000000 T __Z13__wrap_mallocj U _printf
这意味着您使用( U )一个名为__Z13__real_mallocj
的符号,并且在文本段( T )中定义一个名为__Z13__real_mallocj
的符号。 但是您可能需要一个名为__real_malloc
的符号。 为了达到这个目的,你必须说编译器__real_malloc
是一个C风格的函数,像这样:
extern "C" void *__real_malloc(size_t); extern "C" void *__wrap_malloc(size_t c) { printf("My malloc called with %d\n", c); return __real_malloc(c); }
现在nm
的输出是:
00000000 b .bss 00000000 d .data 00000000 r .rdata 00000000 t .text U ___real_malloc 00000000 T ___wrap_malloc U _printf
你可以看到名字_printf
没有改变。 这是因为在头文件中,许多函数已被声明为extern "C"
。
注意:我在cygwin环境中的Windows上执行了上述所有操作。 这就是为什么在外部符号中有一个额外的前导下划线。
如果这是完整的代码,你遇到的问题是你没有实现__real_malloc()
!
顺便说一句,双下划线的标识符是由语言保留的。 你可能想考虑选择不同的名字。