GCC:使用旧C代码时的链接器错误

时间:2013-12-18 03:39:05

标签: c++ c gcc

我遇到了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”的调用因链接器错误而失败,“未定义引用”等等。导致不同行为的两个函数之间有什么区别?

我尝试在“#include”指令中添加“extern C”,因此main.cpp读取:

extern "C"{
    #include "mleak_cpp.h"
}

并在函数声明之前添加关键字“extern”,这次对“foo()”的调用也失败并出现相同的错误。

我感谢你们的任何帮助

2 个答案:

答案 0 :(得分: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文件中,则需要加以保护:

#ifdef __cplusplus
    extern "C" {
#endif 

    /* ... body of header ... */

#ifdef __cplusplus
     }
#endif

此外,当一个文件调用foo但另一个文件定义__foo()时,上述示例中foo()为何起作用尚不清楚。我假设有更多的东西在起作用,例如你的问题中的编辑错误。

答案 1 :(得分: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代码中包含标题时才有效,所以建议这样做我在上面指出的方式。