Я сталкиваюсь с загадочной ситуацией с компилятором GCC. Итак, у меня есть следующие файлы:
//main.cpp
#include "mleak_cpp.h"
int main(int argc, char* argv[])
{
foo();
__memory_malloc(10,"hello",5);
return 0;
}
//mleak_cpp.h
......
void foo(void);
void* __memory_malloc(size_t size, const char* file, int line);
//mleak_cpp.cpp
//definitions of the functions;
void foo(void){printf("foo\n");
void* __memory_malloc(size_t size, const char* file, int line){
printf("%s,%d\n",file,line);
InitDoubleLinkList();
void* p = malloc(size);
if(p == NULL)
return NULL;
__DuLinkList* pListNode;
pListNode = (__DuLinkList*)malloc(sizeof(__DuLinkList));
pListNode->address = p;
pListNode->memorysize = size;
pListNode->file = file;
pListNode->line = line;
InsertBlockToList(pListNode);
return p;
}
По какой-то причине вызов void foo (void) в порядке, но вызов "__memory_malloc" сбрасывается с ошибкой компоновщика, "неопределенной ссылкой" бла-бла. Какая разница между двумя функциями, вызывающими различное поведение?
Я попытался добавить "extern C" в директиву "#include", поэтому main.cpp читает:
extern "C"{
#include "mleak_cpp.h"
}
и добавление ключевого слова "extern" перед объявлениями функций, и на этот раз вызов "foo()" тоже не выполняется с той же ошибкой.
Я ценю любую помощь от вас, ребята
Вы помещаете extern "C"
в неправильное место.
Если main.c
действительно является C файлом, а mleak_cpp.cpp
действительно является функцией C++, тогда вам нужно поставить extern "C"
перед определением __memory_malloc()
следующим образом:
extern "C" void* __memory_malloc(size_t size, const char* file, int line){
// ...
}
Если вы помещаете extern "C"
в файл mleak_cpp.h
, его необходимо mleak_cpp.h
:
#ifdef __cplusplus
extern "C" {
#endif
/* ... body of header ... */
#ifdef __cplusplus
}
#endif
Кроме того, неясно, почему foo
работает в вашем примере выше, когда один файл вызывает __foo()
а другой файл определяет foo()
. Я предполагаю, что в игре есть что-то большее, например, ошибка редактирования в вашем вопросе.
extern "C"
для C++, а не C, и говорит, что имя функции не должно искажаться. В коде C вы никогда не увидите этого. Как правило, вы помещаете его в файлы заголовков, и вы его охраняете, например:
#ifdef __cplusplus
extern "C" {
#endif
/* C and C++ compatible header file body here */
#ifdef __cplusplus
} /* end extern "C" */
#endif
Однако, если вы это сделаете, вам нужно включить заголовочный файл в файлы C и C++, чтобы компилятор C++ знал, использовать C-ссылку.
Вы можете поместить extern "C"
перед определением функции в C++ и оставить его вне заголовка, но это работает только в том случае, если вы включаете только заголовки в C-код, поэтому рекомендуется делать это так, как я указано выше.