[原創]C/C++語言中,如何在main.c或main.cpp中調用另一個.c文件


  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文件之間的函數互相調用問題(三)

2、C語言一個源文件如何調用另一個源文件里的函數

3、C語言為什么無法include另一個源代碼文件

4、cpp到obj再到exe,重定義的問題

5、C/C++不同文件夾下包含頭文件的方法及#include的使用

6、“error LNK2019: 無法解析的外部符號”之分析

7、碰到“error LNK2019: 無法解析的外部符號”

8、3.C++和C混合編程


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM