C 呼叫C鏈結庫會出現的問題

2021-07-30 10:11:58 字數 2019 閱讀 7364

以下是假設舊的c程式庫

c的標頭檔案

/*-----------c.h--------------*/

#ifndef _c_h_

#define _c_h_

extern int add(int x, int y);

#endif

c的原始檔

/*-----------c.c--------------*/

int add(int x, int y)

c++的呼叫

/*-----------cpp.cpp--------------*/

#include "c.h"

void main()

這樣編譯會產生錯誤cpp.obj : error lnk2001: unresolved external symbol "int __cdecl add(int,int)" ([email=?add@@yahhh@z]?add@@yahhh@z[/email]),原因是找不到add的目標模組

這才令我想起c++過載的函式命名方式和c函式的命名方式,讓我們回顧一下:c中函式編譯後命名會在函式名前加以"_",比如add函式編譯成obj檔案時的實際命名為_add,而c++命名則不同,為了實現函式過載同樣的函式名add因引數的不同會被編譯成不同的名字

例如int add(int , int)==>add@@yahhh@z,

float add(float , float )==>add@@yammm@z,

以上是vc6的命名方式,不同的編譯器會不同,總之不同的引數同樣的函式名將編譯成不同目標名,以便於函式過載是呼叫具體的函式。

編譯cpp.cpp中編譯器在cpp檔案中發現add(1, 0);的呼叫而函式宣告為extern int add(int x, int y);編譯器就決定去找[email=add@@yahhh@z]add@@yahhh@z[/email],可惜他找不到,因為c的原始檔把extern int add(int x, int y);編譯成_add了;

為了解決這個問題c++採用了extern "c",這就是我們的主題,想要利用以前的c程式庫,那麼你就要學會它,我們可以看以下標準標頭檔案你會發現,很多標頭檔案都有以下的結構

#ifndef __h

#define __h

#ifdef __cplusplus

extern "c"

#endif

#endif /*__h*/

如果我們仿製該標頭檔案可以得到

#ifndef _c_h_

#define _c_h_

#ifdef __cplusplus

extern "c"

#endif

#endif /* _c_h_ */

這樣編譯

/*-----------c.c--------------*/

int add(int x, int y)

這時原始檔為*.c,__cplusplus沒有被定義,extern "c" {}這時沒有生效對於c他看到只是extern int add(int, int);

add函式編譯成_add(int, int);

而編譯c++原始檔

/*-----------cpp.cpp--------------*/

#include "c.h"

void main()

這時原始檔為*.cpp,__cplusplus被定義,對於c++他看到的是extern "c" 編譯器就會知道 add(1, 0);呼叫的c風格的函式,就會知道去c.obj中找_add(int, int)而不是[email=add@@yahhh@z]add@@yahhh@z[/email];

這也就為什麼dll中常看見extern "c" {},windows是採用c語言編制他首先要考慮到c可以正確呼叫這些dll,而使用者可能會使用c++而extern "c" {}就會發生作用

當原來的c語言寫的標頭檔案裡面沒有考慮這個問題的時候,可以寫成這樣:

#include

#include

extern "c"

這樣就可以在c++裡面用別人寫的c語言的東西了。

C呼叫C 鏈結庫

c呼叫c 鏈結庫 1.編寫c 編寫函式的時候,需要加入對c的介面,也就是extern c 2.由於c不能直接用 class.function 的形式呼叫函式,所以c 中需要為c寫乙個介面函式。例如本來要呼叫student類的talk函式,就另外寫乙個cfun 專門建乙個student類,並呼叫tal...

C 呼叫C鏈結庫

c 呼叫c鏈結庫 c 呼叫c語言的鏈結庫,其實相對c呼叫c 簡單。因為c 本來就向下相容c吧 個人見解 簡單說來原因就是未經處理的c 編譯後函式名可能變為 helloc 之類的,而c 編譯後函式名卻不是這樣,所以就對不上。詳細解釋見 需要在include c的檔案的時候加上extern c c.h ...

C 呼叫C 動態鏈結庫dll

在過程中發現兩種方法解決問題 一種是非託管c 建立的dll庫,需要用靜態方法呼叫。這種方法無法在c 的reference中直接引用,而是要用靜態呼叫的方法,其他部落格已經介紹的很詳盡,唯一需要補充的是,c 檔案需要先 usingsystem.runtime.interopservices 之後才可以...