有没有人用C ++包装函数的例子?

时间:2010-09-29 21:47:18

标签: c++ linux gcc g++

我在网上搜索了很多但我找不到一个与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

创建此错误的代码如下(如果我使用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

2 个答案:

答案 0 :(得分:16)

使用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 )中定义一个名为{{1 }}。但是你可能想要一个名为__Z13__wrap_mallocj的符号。要实现这一点,你必须说编译器__real_malloc是一个C风格的函数,如下所示:

__real_malloc

现在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

注意:我在cygwin环境中的Windows上完成了以上所有操作。这就是为什么外部符号中还有一个额外的前导下划线。

答案 1 :(得分:0)

如果这是完整的代码,那么您遇到的问题是您没有实现__real_malloc()

顺便说一句,带有双下划线的标识符由语言保留。您可能想考虑选择不同的名称。