GCC: ошибка компоновщика при работе со старым кодом C

0

Я сталкиваюсь с загадочной ситуацией с компилятором 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()" тоже не выполняется с той же ошибкой.

Я ценю любую помощь от вас, ребята

  • 0
    Вы должны опубликовать точное сообщение об ошибке вместо бла-бла.
Теги:
gcc

2 ответа

3
Лучший ответ

Вы помещаете 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(). Я предполагаю, что в игре есть что-то большее, например, ошибка редактирования в вашем вопросе.

  • 0
    «main» должен быть файлом cpp, если это имеет значение. Извините, опечатка. Чем обусловлено поведение "foo" и "memory_malloc"?
  • 0
    Обновление: ну .. тогда забудь про foo. Коллега предположил, что причиной может быть «__». Как бы я ни сомневался, я попробовал, что объясняет вызов «__foo» в основном.
1

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-код, поэтому рекомендуется делать это так, как я указано выше.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню