搜尋

首頁  >  問答  >  主體

c++ - extern "C"按着别人博客写的测试程序总是报错?

三个文件:

/* c语言头文件:cExample.h */
#ifndef C_EXAMPLE_H
#define C_EXAMPLE_H
extern int add(int x,int y);     //注:写成extern "C" int add(int , int ); 也可以
#endif
/* c语言实现文件:cExample.c */
#include "cExample.h"
int add( int x, int y )
{
 return x + y;
}
// c++实现文件cppFile.cpp,调用add
extern "C"
{
#include "cExample.h"
}
//注:此处不妥,如果这样编译通不过,换成 extern "C" int add(int , int ); 可以通过
extern "C" int add(int, int);
int main(int argc, char* argv[])
{
    add(2, 3);
    return 0;
}

这都是别人博客的代码,他说不会错,然后我在VS2015运行了,报错,错误 LNK2019 无法解析的外部符号 _add,该符号在函数 _main 中被引用。我换了好几个人博客把代码复制进去都是报同样的错误,我不知道是什么问题,上面注释里的我也试了还是报错。

大家讲道理大家讲道理2806 天前656

全部回覆(2)我來回復

  • 天蓬老师

    天蓬老师2017-04-17 15:05:40

    找到錯誤了,

    我沒有把.c和.h拖至工程裡,只是放在該目錄下了。已解決。

    回覆
    0
  • PHP中文网

    PHP中文网2017-04-17 15:05:40

    剛剛看到,樓主已經自己解決問題了。不過,這個例子在 gcc 這裡還是錯的:

    $ g++ -std=c++11 -pedantic -Werror cExample.c cppFile.cpp -o demo
    /tmp/cceHYgc4.o: In function `main':
    cppFile.cpp:(.text+0xf): undefined reference to `add'
    collect2: error: ld returned 1 exit status

    這是因為c++ 編譯器在編譯cExample.c 的時候,雖然你的意圖是呼叫C 編譯器去編譯add 函式的程式碼,但c++ 編譯器不知道這些,它認為add 函式是一個c++ 函數,於是,編譯後add 函數的名字會被改為_Z3addii。這樣,即使你在 cppFile.cpp 檔案中指定要使用 C 版本的 add 函數,但是這個函數事實上不存在,所以就出現了無法解析的外部符號。

    要解決這個問題,只需要在 cExample.h 檔案中這樣寫:

    #ifndef C_EXAMPLE_H
    #define C_EXAMPLE_H
    extern "C" {
            int add(int x, int y);
    }
    #endif

    如果 cExample.h 中宣告的函數要被其他 C 模組調用,那麼嚴謹的寫法是:

    #ifndef C_EXAMPLE_H
    #define C_EXAMPLE_H
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    int add(int x, int y);
    
    #ifdef __cplusplus
    }
    #endif
    #endif

    至於為什麼在 VS 中將 cExample.{h,c} 拖曳到工程中就可以解決問題,這就不得而知了。猜測是 VS 遇到文件後綴名為 .c 的文件,就自動用 C 編譯器去編譯。

    回覆
    0
  • 取消回覆