C/C++語言中,如何在main.cpp中調用另一個.c文件主要有5種思路:
1、在VS2012 IDE中,將被引用的.c文件后綴名全部修改為.h,然后通過IDE的解決方案資源管理器中鼠標右鍵單擊“頭文件”-"添加"-“現有項”,選中修改后綴名后的.h文件-"添加",將待引用的文件添加到工程中。

添加到“頭文件”而不是“源文件”的作用:主要是使頭文件的項類型屬性為“C/C++ 標頭”,而不是“C/C++ 編譯器”。后者是將該文件獨立編譯成目標文件*.obj。用戶可右鍵單擊某個.h文件-屬性-配置屬性-常規-項類型,來查看。

接着在main.cpp文件中,包含所需要使用頭文件:
#include "13lman.h"
然后在需要的地方,直接調用該函數即可,如下:
js=lman(3,1,200,f,q,r,h,y,x,p,g);
2、不用修改文件擴展名,直接將待引用的.c文件添加到“源文件”下面,按照1的步驟將待引用的文件的"項類型“修改為“C/C++ 標頭”。該方法的本質是將*.c文件當做*.h使用。如下圖所示:


接着在main.cpp文件中,包含所需要使用.c文件:
#include "13lman.c"
然后在需要的地方,直接調用該函數即可,如下:
js=lman(3,1,200,f,q,r,h,y,x,p,g);
3、首先,在IDE中右鍵選中頭文件-添加-新建項-Visual C++-頭文件(.h)-輸入文件名,創建新的.h文件。如下圖所示:

接着,在function.h文件來聲明這些待調用的函數:
#ifndef __FUNCTION_H__ #define __FUNCTION_H__ int rinv(double a[],int n); int lman(int n,int m,int k,double f[],double q[],double r[],double h[],double y[],double x[],double p[],double g[]); #endif
然后,按照2中的步驟,將待引用的.c文件添加到源文件節點下面。將其項類型設置為“C/C++ 編譯器”,預編譯頭設置為“不使用預編譯頭”。如下圖所示:


接下來,在待引用的.c文件中包含function.h頭文件(貌似這一步不用也可以編譯-鏈接-運行成功???):
#include "function.h"
緊接着,在主調用文件main.cpp中,文件中包含待引用的.c文件:
#include "13lman.c"
最后,在需要的直接調用該函數即可,如下:
js=lman(3,1,200,f,q,r,h,y,x,p,g);
4、如果main.cpp需要調用的.c文件還需要依賴其它.c文件,則可以按照下圖所示的方法設置各個文件的編譯屬性:

前提是:所有的.c文件添加到“源文件”節點下面,將其項類型設置為“C/C++ 編譯器”,預編譯頭設置為“不使用預編譯頭”(除了最后一個.c文件)。
接着,在主調用文件main.cpp中,文件中包含待引用的.c文件:
#include "13lman.c"
然后,在13lman.c文件中包含所依賴的4rinv.c文件:
#include "4rinv.c"
最后,在需要的直接調用該函數即可,如下:
js=lman(3,1,200,f,q,r,h,y,x,p,g);
5、 所有的.c文件添加到“源文件”節點下面,將其項類型設置為“C/C++ 編譯器”,預編譯頭設置為“不使用預編譯頭”。如果直接編譯-鏈接會輸出“error LNK2019: 無法解析的外部符號”鏈接錯誤。
問題原因:C語言和C++語言混編,因為C++支持函數重載所以C++編譯器生成的庫文件中的函數名會面目全非,例如C編譯器會生成 _readRegmark 這個函數名,而C++編譯器則生成了"void __cdecl readRegmark(char *)" (?readRegmark@@YAXPAD@Z)這么個函數名。當你的函數是用C語言寫的,VS編譯器會按C語言規則編譯,但鏈接器卻不知道還傻傻的用C++規則的函數名去找,當然就找不到了。
解決辦法:在C語言的頭文件或主動調用的main.cpp文件的最開始部分加入如下代碼:
#ifdef __cplusplus extern "C" { #endif void readRegmark(char *regmark); //這里寫函數聲明 #ifdef __cplusplus } #endif
或者,更簡潔一些:
extern "C" { int lman(int n,int m,int k,double f[],double q[],double r[],double h[],double y[],double x[],double p[],double g[]); }
這樣的話就可以編譯-鏈接成功了。上面的解決辦法適用於待調用的.c文件中的函數還依賴於其他文件中的其它函數的情況。如果主動調用文件main.cpp還需要使用其它.c文件的函數,也可以用同樣的方法解決。推薦使用第一種方法。因為第一種方法既能夠讓.cpp文件能夠包含這個.c文件,又能讓其它.c文件能夠包含這個.c文件。需要注意的是:__cplusplus是C++編譯器內置的宏。
對OpenGL比較熟悉的用戶可能會發現在OpenGL的頭文件GL.h中的開頭和結尾部分就使用了上面的用法,如下圖所示:
開頭部分 結尾部分

參考鏈接:
1、同一個C語言工程不同C文件之間的函數互相調用問題(一)、同一個C語言工程不同C文件之間的函數互相調用問題(二)、同一個C語言工程不同C文件之間的函數互相調用問題(三)
5、C/C++不同文件夾下包含頭文件的方法及#include的使用
6、“error LNK2019: 無法解析的外部符號”之分析
