У кого-нибудь есть пример для переноса функции в C ++? - PullRequest
4 голосов
/ 30 сентября 2010

Я много искал в Интернете, но не смог найти пример, который работает с 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 ]

16 голосов
/ 30 сентября 2010

Когда вы используете компилятор 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__wrap_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".

Примечание. Я проделал все вышеперечисленное в Windows в среде cygwin.Вот почему во внешних символах есть дополнительное подчеркивание.

0 голосов
/ 30 сентября 2010

Если это полный код, проблема в том, что вы не реализовали __real_malloc()!

И, кстати, идентификаторы с двойным подчеркиванием зарезервированы языком. Возможно, вы захотите выбрать разные имена.

...