久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

extern "C" 解析

 啟_明_星 2010-04-08

時常在cpp的代 碼之中看到這樣的代碼: 

"cLr:UNPHdGBSD愛好者樂園+f&mVC,~)wyl

#ifdef __cplusplus
]#r7WE^-z i4RDHextern "C" {BSD愛好者樂園;ZPL2r-_ E%?x
#endif

ir8c:N+b2`$Kax

T*V} A%f_.n:U/m//一段代碼BSD愛好者樂園/B4L.m k!J P&H

t1ZE1H5o+~1B1S#ifdef __cplusplusBSD愛好者樂園K;D)H&@]5~
}
!Oj.Q#F5RsK#endif BSD愛好者樂園+ID#RM"Z0x X

BSD愛好者樂園B)MW,Jhe;{v#P

這樣的代碼到底是什么意思呢,?首先,__cplusplus是cpp中的自定義宏,,那么定義了這個宏的話表示這是一段cpp的代碼,也就是說,,上面的代 碼的含義是:如果這是一段cpp的代碼,,那么加入extern "C"{和}處理其中的代碼。

'G6ertj5KbBSD愛好者樂園x!l(Q Fu?E

  要明白為何使用extern "C",,還得從cpp中對函數(shù)的重載處理開始說起,。在c++中,,為了支持重載機制,在編 譯生成的匯編碼中,,要對函數(shù)的名字進行一些處理,,加入比如函數(shù)的返回類型等等.而在C中,只是簡單的函數(shù)名字而已,,不會加入其他的信息.也就是說:C++ 和C對產(chǎn)生的函數(shù)名字的處理是不一樣的.

sUk;G ?\n'{D

5q7|D\V  比如下面的一段簡單的函數(shù),,我們看看加入和不加入extern "C"產(chǎn)生的匯編代碼都有哪些變化:

t#HJIm.W:G

m3Z0s$M:Mxint f(void)BSD愛好者樂園h0K4i+t2L1yx
{
Q Uy)qkreturn 1;BSD愛好者樂園T9Ujn1f
BSD愛好 者樂園#\C d_u:l7I)H

BSD愛好者樂園Q-F w;|)wS n ^

  在加入extern "C"的時候產(chǎn)生的匯編代碼是:

6k~/vq4S

U*m#zhZ$XX:g.file "test.cxx"BSD愛好者樂園"rS_@(UlGo9~ z
.text
Z8_f1Ek#N,ey)\.align 2BSD愛好者樂園bS Z7[KF
.globl _fBSD愛好者樂園 [(GA V@U.|
.def _f; .scl 2; .type 32; .endefBSD愛好者樂園e/J?B1K#s| _"\@6s&`0T
_f:
9R?p1q9V1GMpushl %ebpBSD愛好者樂園wBA:W,K@$sL
movl %esp, %ebpBSD愛好者樂園1Q.tJ#Vu7Q'A3@t
movl $1,, %eax
V;rmwCa~ Mm#Opopl %ebpBSD愛好者樂園~zrc2T
ret BSD愛好者樂園UF C9q2}

~.Q^-@7Yoy]al 但是不加入了extern "C"之后

.rn-L}auy:m1~+B

T/At4^*t)c.file "test.cxx"BSD愛好者樂園+T\ Xun7ZNJ
.textBSD愛好者樂園}zE,p]7`2|S*H
.align 2BSD愛好者樂園j+l)t;z5OVH
.globl __Z1fvBSD愛好者樂園I"L(L1sw f'g@i
.def __Z1fv; .scl 2; .type 32; .endef
/iB-L]C$\"Y1?6fG`__Z1fv:
jgqSj3A;orpushl %ebpBSD愛好者樂園 e M0R4R"]6BZM,\'g
movl %esp,, %ebp
XXHo A Vmrmovl $1, %eaxBSD 愛好者樂園V M,iY;t%` m ~
popl %ebp
0g"J)pU YjOcR?Bret 

z&MW@![ X{'~L$@

@!d9u+bt _~  兩段匯編代碼同樣都是使用gcc -S命令產(chǎn)生的,,所有的地方都是一樣的,,唯獨是產(chǎn)生的函數(shù)名,一個是_f,,一個是__Z1fv,。

.D }E:h7OBSD愛好者樂園#wV3m?Q }k

  明白了加入與不加入extern "C"之后對函數(shù)名稱產(chǎn)生的影響,我們繼續(xù)我們的討論:為什么需要使用extern "C"呢,?C++之父在設(shè)計C++之時,,考慮到當(dāng)時已經(jīng)存在了大量的C代碼,為了支持原來的C代碼和已經(jīng)寫好C庫,,需要在C++中盡可能的支持C,,而 extern "C"就是其中的一個策略。 BSD愛好者樂園4w?*@W E,?:a6YG)_QM
試想這樣的情況:一個庫文件已經(jīng)用C寫好了而且運行得很良好,,這個時候我們需要使用這 個庫文件,,但是我們需要使用C++來寫這個新的代碼。如果這個代碼使用的是C++的方式鏈接這個C庫文件的話,,那么就會出現(xiàn)鏈接錯誤.我們來看一段代碼: 首先,,我們使用C的處理方式來寫一個函數(shù),也就是說假設(shè)這個函數(shù)當(dāng)時是用C寫成的:

f?T @E7bV!y0T:DTBSD愛好者樂園@ bH7gVm

//f1.c
-w|ZN T9T3jextern "C"
'MTlW B{BSD愛好者樂園/dx _3I?J'P#b
void f1()BSD愛好者樂 園;g"T,r.b(z9_4RX+dv:u*lS
{BSD愛 好者樂園!T0w ]ok-}#u]*]l??
return;BSD愛好者樂園 @^'D${9C+g \P
}
s]~(s.^y"wucA.S)v

1E@s4\ Q(N'ZyBSD愛好者樂園,y+HR%s-X4u$sY0}:z,k

  編譯命令是:gcc -c f1.c -o f1.o 產(chǎn)生了一個叫f1.o的庫文件,。再寫一段代碼調(diào)用這個f1函數(shù):

$h9B c-v{QJ2oBSD愛好者樂園#U)uE U/I-M?A7B vs7_

// test.cxx
+ptz5I*}5~ ok//這個 extern表示f1函數(shù)在別的地方定義,,這樣可以通過BSD愛好者樂園e8X3Jz ]X'J7q:X@ X i1J
//編譯,但是鏈接的時候還是需要BSD愛好者樂園?zI(V_l G
//鏈接上原來的庫文件.
[ v8rj.I]extern void f1();BSD愛好者樂園 Q%x k\9D"}sd,d

BSD愛好者樂園 _$I4`:C~ D

int main()BSD愛好者樂園 c$n zaB&s
{
:c_&N1ZKB`$S!jf1();

c)\j?] L5dfGs9{#v

4|aQ.U&Kreturn 0;
$Q9IMQ'i?{

BP0I?ArBSD愛好者樂園&N]-YU!G AEB5_V&n

通過gcc -c test.cxx -o test.o 產(chǎn)生一個叫test.o的文件,。然后,,我們使用gcc test.o f1.o來鏈接兩個文件,可是出錯了,,錯誤的提示是:BSD愛好者樂園&ri0m L |7U?V t*F

~-Y,W [2oVTtest.o(.text + 0x1f):test.cxx: undefine reference to 'f1()' BSD愛好者樂園?c8[[`e)r-Yv

BSD 愛好者樂園-M.Gg0@3JR3r){x

  也就是說,,在編譯test.cxx的時候編譯器是使用C++的方式來處理 f1()函數(shù)的,但是實際上鏈接的庫文件卻是用C的方式來處理函數(shù)的,,所以就會出現(xiàn)鏈接過不去的錯誤:因為鏈接器找不到函數(shù),。

3I2BWG"u`$kBSD 愛好者樂園L Lz,U+L?'AL

  因此,,為了在C++代碼中調(diào)用用C寫成的庫文件,就需要用extern "C"來告訴編譯器:這是一個用C寫成的庫文件,,請用C的方式來鏈接它們,。BSD愛好者樂園 ro&E)B8E5x

BSD愛好者樂園B _6lQ3@:E/K!]{1D

  比如,現(xiàn)在我們有了一個C庫文件,,它的頭文件是f.h,,產(chǎn)生的lib文件是f.lib,那么 我們?nèi)绻贑++中使用這個庫文件,,我們需要這樣寫:BSD愛好者樂園,nGv ['B"idx'Iy}
extern "C"
MEf5x*H{BSD愛好者樂園&j:M3o%tk9O8u3yw?W
#i nclude "f.h"
S;C0I UL[9p3L

K T"XG%f @,XBSD愛好者樂園/u mZ`%Z

  回到上 面的問題,,如果要改正鏈接錯誤,我們需要這樣子改寫test.cxx:BSD愛好者樂園 O8U&GfL}$[

y5Wp(M*|extern "C"
+@,@%a:{;wl{
(qw'Fo7plGextern void f1();
#_3Xh`D _2R}BSD愛好者樂園3x@ Cj'GZ c

BSD 愛好者樂園 Y&~t\M Z(O

int main()BSD愛好者 樂園c:\f?sSL!~3Bt
{
J W*pI:A1u$ef1();

Nr @ H-`%Y&g

\5I no,x1Kreturn 0;
[ jHf\:Lk J oBSD愛好者樂園5rv7deB E O(HLw:X

BSD愛好者樂園9SB)h S9X3n W$ct

  重新編譯并且鏈接就可以過去了.BSD愛好 者樂園0g,j:^ek_ s$B*o

O9`;``9v9^3p  總結(jié)BSD愛好者樂園T]'O]7tvz

BSD愛好者樂園epE9D~Z?

  C和C++對函數(shù)的處理方式是不 同的.extern "C"是使C++能夠調(diào)用C寫作的庫文件的一個手段,,如果要對編譯器提示使用C的方式來處理函數(shù)的話,,那么就要使用extern "C"來說明。
A l I2m?)H 

%a;h1]{q^,ZBSD 愛好者樂園ob_(I}Xv)K


g c2r S!pJi 
o Gi?B/H;Z+L0b~G 
L hh,k(aNx_作者:宋寶華  e-mail:[email protected] 出處:太平洋電腦網(wǎng)BSD愛好者樂園.h_ \9\'Q[

g'tF~1Rj(\^L1.引言

*?}!G V!c;Cs!JBSD愛好者樂園7u0Y)zGb7yFO"e

C++語言的創(chuàng)建初衷是“a better C”,,但是這并不意味著C++中類似C語言的全局變量和函數(shù)所采用的編譯和連接方式與C語言完全相 同,。作為一種欲與C兼容的語言,C++保留了一部分過程式語言的特點(被世人稱為“不徹底地面向?qū)ο?#8221;),,因而它可以定義不屬于任何類的全局變量和函數(shù),。 但是,C++畢竟是一種面向?qū)ο蟮某绦蛟O(shè)計語言,,為了支持函數(shù)的重載,,C++對全局函數(shù)的處理方式與C有明顯的不同。BSD愛好者樂園%SRujz4F6H

BSD愛好者樂園wZ.`v!z[

2.從標(biāo)準(zhǔn)頭文件說起

^ f oc:n3`G0@

qE)nqb0h9|oy某 企業(yè)曾經(jīng)給出如下的一道面試題:BSD愛好者樂園qJ@*M*j/X e&?

,@6E6gn8s S面試題

7Yza7]DR.vbBSD愛好者樂園Kr+cQ m%pn

為什么標(biāo)準(zhǔn)頭文件都有類似以下的結(jié)構(gòu),?BSD愛好者樂園3w#io9R C'X,Vs3wG

BSD愛好者樂園 {?d!InCX?xN

   #ifndef __INCvxWorkshBSD愛好者樂園%y-Y\ I6m3U:a

v%CI [)dZ   #define __INCvxWorksh

w3TLX_

dSK!e~   #ifdef __cplusplus

/tOb*Bn7T/qHBSD愛好者樂園x)wOo&ow(Vo4L

   extern "C" {BSD愛好者樂園FIG Jf`2C

DHj `_sbl   #endifBSD愛好者樂園)OA"OtR'P8Cl

~ p0KWI?8v'j~   /*...*/

}P]*D4x#uJ

C` \Q"x)~ ^   #ifdef __cplusplus

l%y@`!_.H%bb

o ^2d JhX   }BSD愛好者樂園9@MFJ"|

,T*A.v V[+GV6tR|   #endifBSD愛好者樂園 H5dXx EoE$e]

BSD愛好者樂園.EP1nH qJ4q0A'D Z$O

   #endif /* __INCvxWorksh */

:Q vZ `*D5M,r

4Et4Qav(N6J&q分 析

1C6E,oGLUH ?c

,lw.gkp9^H?^:WB顯然,,頭文件中的編譯宏“#ifndef __INCvxWorksh、#define __INCvxWorksh,、#endif” 的作用是防止該頭文件被重復(fù)引用,。

IZ!Q#r*t;m-N c,O

\S/lA1h0xI那么

"i z#YZHC h

8wS7Xkn8|   #ifdef __cplusplusBSD愛好者樂園DT6Y*FR9y o5l

BSD愛好者樂園mX0]2Nkt2h#?W u

   extern "C" {

#}9^(~5W^]BSD愛好者樂園Gc ^[email protected]Gp M

   #endif

,dA?Lt)w6WdY`#Mq

F a8{]y,S K  #ifdef __cplusplusBSD愛好者樂園` c(X9j.Fia

BSD愛好者樂園m \_?C Nl(i

   }

d{[9ceE

,t_1p:ZT3hZ   #endifBSD愛好者樂園:@F.`[e\

k#ICK&t w M e9M`;k的作用又是什么呢?我們將在下文一一道來,。

/r |1xF |,d'`*]BSD愛好者樂園;K3w&d%C"p i2NRy:x

3.深層揭密 extern "C"

:gr7^(yGC zP!KGC

H-M6G!x6fextern "C" 包含雙重含義,,從字面上即可得到:首先,被它修飾的目標(biāo)是“extern”的,;其次,,被它修飾的目標(biāo)是“C”的。讓我們來詳細解讀這兩重含義,。BSD愛好者樂園stDE9L$JK

BSD愛好者樂園k PrWa1k EBc6Y

(1)       被extern "C"限定的函數(shù)或變量是extern類型的,;

aot a5XBSD 愛好者樂園F-G"B6ag b

extern是C/C++語言中表明函數(shù)和全局變量作用范圍(可見性)的關(guān)鍵字,該關(guān)鍵字告訴編譯器,其聲明的函數(shù)和變量可以在本 模塊或其它模塊中使用,。記住,下列語句:

Q0zg?^A:g9U!hF

F.Uk6To{ ?'B7Yextern int a;BSD愛好者樂園|)^]'w5|

4P_3?g:t [M*NtM僅僅是一個變量的聲明,,其并不是在定義變量a,, 并未為a分配內(nèi)存空間。 變量a在所有模塊中作為一種全局變量只能被定義一次,,否則會出現(xiàn)連接錯誤,。

O.gb O?u#e-aBSD愛好者樂園`0c q ]#R/^

通常,在模塊的頭文件中對本模塊提供給其它模塊引用的函數(shù)和全局變量以關(guān)鍵字extern聲明,。例如,,如果模塊B欲引用該 模塊A中定義的全局變量和函數(shù)時只需包含模塊A的頭文件即可。這樣,,模塊B中調(diào)用模塊A中的函數(shù)時,,在編譯階段,模塊B雖然找不到該函數(shù),,但是并不會報 錯,;它會在連接階段中從模塊 A編譯生成的目標(biāo)代碼中找到此函數(shù)。BSD愛好者樂園3V n+Pw7E8J jYp1`9I#r

\qww'vh與 extern對應(yīng)的關(guān)鍵字是static,,被它修飾的全局變量和函數(shù)只能在本模塊中使用,。因此,一個函數(shù)或變量只可能被本模塊使用時,,其不可能被 extern “C”修飾,。

2X*@#Pvry!u?:l

(u*D R9b%K#m(2)       被extern "C"修飾的變量和函數(shù)是按照C語言方式編譯和連接的;BSD愛好者樂園%O}2pb6Mf

BSD愛好者樂園 P/gFvP!@

未加extern “C”聲明時的編譯方式

6UTR3|CBSD愛好者樂園S z0e1v&X2`g N

首先看看C++中對類似C的函數(shù)是怎樣編譯的,。BSD愛好者樂園 9z(iB8GgZ1p!Ui

GU0{8`4mk/^H1@I作 為一種面向?qū)ο蟮恼Z言,,C++支持函數(shù)重載,而過程式語言C則不支持,。函數(shù)被C++編譯后在符號庫中的名字與C語言的不同,。例如,假設(shè)某個函數(shù)的原型為:

A^$n3ma$l5|BSD愛好者樂園 W|'dT7q

void foo( int x, int y );BSD愛好者樂園&Eik%w+}p~s%t

BSD愛好者樂園a Q&F5]$PN*z9O1u

該函數(shù)被C編譯器編譯后在符號庫中的名字為_foo,,而C++編譯器則會產(chǎn)生像 _foo_int_int之類的名字(不同的編譯器可能生成的名字不同,,但是都采用了相同的機制,生成的新名字稱為“mangled name”),。_foo_int_int這樣的名字包含了函數(shù)名,、函數(shù)參數(shù)數(shù)量及類型信息,C++就是靠這種機制來實現(xiàn)函數(shù)重載的,。例如,,在C++中,函 數(shù)void foo( int x, int y )與void foo( int x, float y )編譯生成的符號是不相同的,后者為_foo_int_float,。

cG s(O,e5u p^{[

@dNW3~ B9rR7e同樣地,,C++中的變量除支持局部變量外,還支持類成員變量和全局變量,。用戶所編寫程序的類成員變量可能與全局變量同名,,我 們以"."來區(qū)分。而本質(zhì)上,,編譯器在進行編譯時,,與函數(shù)的處理相似,也為類中的變量取了一個獨一無二的名字,,這個名字與用戶程序中同名的全局變量名字不 同,。

-@;H"G3|:W+H Q E

}$q?^^wIr%^6A$_未加extern "C"聲明時的連接方式BSD愛好者樂園 ?|!f F0Jckj y

BSD愛好者樂園2LoEu?B,U7M

假設(shè)在C++中,模塊A的頭文件如 下:

-~c*t)j MS@PLBSD愛好者樂園vv0],V!irm ~q

// 模塊A頭文件 moduleA.hBSD愛好者樂園N g Gpl%@`3@

BSD愛好者樂園:h7F Z B4p7mM

#ifndef MODULE_A_H

4yhr%] eY&M!l.y

1c,?C#y `"SeC1q[A@       #define MODULE_A_H

1o stX$DL TUBSD愛好者樂園w}mrP3q-H

    int foo( int x, int y );BSD愛好者樂園9i(UJ!e'[

BSD愛好者樂園M5dOns(l0E

#endif

;W#]?^ si.q

%K+GMD"z"BW!S0G在模塊B中引用該函數(shù):BSD 愛好者樂園6[ Sj0Gd+J

BSD愛好者樂園.]+zP ~I0rho W%W2j

// 模塊B實現(xiàn)文件 moduleB.cppBSD愛好者 樂園%n'K+m(J$r RA;J

K2h9[,T,S#i nclude "moduleA.h"

&A]&y_ d$L&`F

,PaF-r&tw|[ {foo(2,3);

)Q V9p1r ]E3D q

VZv#JC,_0K?AV5v實際上,,在連接階段,,連接器會從模塊A生成的 目標(biāo)文件moduleA.obj中尋找_foo_int_int這樣的符號!

$D9eo `+T"PBSD愛好者樂園(xQ%a2]5q?q6v

加extern "C"聲明后的編譯和連接方式BSD愛好者樂園 P&c?9l3QO&[

D9K_"@%w9U:w ^ a加extern "C"聲明后,,模塊A的頭文件變?yōu)椋?/p> ztw XA|T2GBSD愛好者樂園b9ECC^-d)m

// 模塊A頭文件 moduleA.hBSD愛好者樂園V8@2s;~T I

?)BME9P FvJJ#ifndef MODULE_A_H

^7m"I(TZ&vB5A&^BSD愛好者樂園F-Om!y&{*gf

       #define MODULE_A_HBSD愛好者樂園^m Gl Vx mW"TNv

BSD愛好者樂園'Qpj {5S0t]Z z

    extern "C" int foo( int x, int y );BSD愛好者樂園1v.m&C8N/U"X$_-|1~

+P;L$e.OPH Z#endifBSD愛好者樂園 m Tmc5R d#Z#z6@

BSD愛好者樂園d[B Sn,}

在模塊B的實現(xiàn)文件中仍然調(diào)用foo( 2,3 ),,其結(jié)果是:

#aO1T)\/\BSD愛好者樂園.Z8^x c?t??!Qq

(1)模塊A編譯生成foo的目標(biāo)代碼時,沒有對其名字進行特殊處理,,采用了C語言的方式,;BSD愛好者樂園1s5{Z-y3m6\:^

f}6^;^(pXO(2)連接器在為模塊B的目標(biāo)代碼尋找foo(2,3)調(diào)用 時,尋找的是未經(jīng)修改的符號名_foo,。

B\5N3GAfe5jBSD愛好者樂園'D6a5o?~}vU

如果在模塊A中函數(shù)聲明了foo為 extern "C"類型,,而模塊B中包含的是extern int foo( int x, int y ) ,則模塊B找不到模塊A中的函數(shù),;反之亦然,。BSD愛好者樂園#?4^Fp'{ c-U

%\V2M*\X lLN所以,可以用一句話概括extern “C”這個聲明的真實目的(任何語言中的任何語法特性的誕生都不是隨意而為的,,來源于真實世界的需求驅(qū)動,。我們在思考問題時,不能只停留在這個語言是怎么 做的,,還要問一問它為什么要這么做,,動機是什么,這樣我們可以更深入地理解許多問題):

_#Rw&K'g @2s,WOE

3e#z)k"J)s+L awx{實 現(xiàn)C++與C及其它語言的混合編程,。

k3J z*{/GaBSD愛好者樂園m$p?~-ML

明白了C++中extern "C"的設(shè)立動機,,我們下面來具體分析extern "C"通常的使用技巧。BSD愛好者樂 園_ G%Pp$B

BSD愛好者樂園/_9p c#`5EM$O

4.extern "C"的慣用法BSD愛好者樂園 \1e,|%P,H?{\

BSD愛好者樂園8{? qjH \Z.JZ

(1)在C++中引用C語言中的函數(shù)和變量,,在包含C語言頭文件(假設(shè)為cExample.h)時,,需進行下列處理:

f1a M;]N'\'Bg

Kr$r%v%q }A-sextern "C"BSD愛好者樂園0^$hN vwY U

*M/l5i6|b9fe2q{

N.dj3nA6BdBSD愛好者樂園.T&Gb3DS&~PYz

#i nclude "cExample.h"

3U OJ8a?^Q1bRk5\p

mk%IR aPk k}BSD愛好者樂園)k XT I}{

BSD愛好者樂園|V g9?6k6r

而在C語言的頭文件中,,對其外部函數(shù)只能指定為extern類型,C語言中不支持extern "C"聲明,,在.c文件中包含了extern "C"時會出現(xiàn)編譯語法錯誤,。

tfa8zw/Xl

,\v WR?q!f5O筆者編寫的C++引用C函數(shù)例子工程中包含的三個文件的源代碼如下:BSD愛好者樂園qG W Fw0a7I{9z

BSD 愛好者樂園"og;j"o+n/Z5J6]0@

/* c語言頭文件:cExample.h */BSD愛好者樂園.nJ ppK&U&U]$Z-U|?U

t4]7C3Af/tG;uk#ifndef C_EXAMPLE_HBSD愛好者樂園0sd9x/pa

BSD愛好者樂園1NrxH7v

#define C_EXAMPLE_HBSD愛好者樂園NQ1O vu[f Q

BSD愛好者樂園!i;jvGJ#m,R4i

extern int add(int x,int y);

'ge5y8K`W3zGBSD愛好者樂園f*xN l2z]TQ

#endif

UG] ? D H'oBSD愛好者樂園B'zs1{"U4C:rn,|8]~

/* c語言實現(xiàn)文件:cExample.c */BSD愛好者樂園oC)_)xjP B \@}D.k

BSD愛好者樂園3n.C c-\%h#G%}%n

#i nclude "cExample.h"BSD 愛好者樂園8D*FU6~ ~5R3F4P,}

4k8\C4|"Xs_&`int add( int x, int y )

Q0Y!];k @$Q1k7niF?p iBSD愛好者樂園;n"?b%[:l[(G{J

{BSD愛好者樂園f&W:F3D4{[-ei1?m8o

8_2t6G'F n_1X%q-Jr       return x + y;

z9N"c3n"eNuA?;MqrBSD愛好者樂園@&D?1z4j

}BSD愛好者樂園J]4ZS6j/fJE&R

XZ8}@Q// c++實現(xiàn)文件,調(diào)用add:cppFile.cppBSD愛好者樂園$M0axe;SvQ3?#`

BSD愛好者樂園o H)k0P)S.o

extern "C"

-Y;m0piRZ-W+sBSD愛好者樂園0y:M$g'T\W:}

{

kK"uNA L0G)H

3D5fN7X+B7vz*Q#i nclude "cExample.h"

e[W5J F9P2fvw1g%qBSD愛好者樂園6["YtGI(`K4Zw;X/_

}

2H l9U5TM/p`j`dv

%^x2qE%p Ivint main(int argc, char* argv[])

r'fo ga.Eg,rgBSD愛好者樂園2l @D r^7L"kSA.mS

{BSD愛好者樂園ZO J5I"R;G {

BSD愛好者樂園U1q%P`;V*Gy WCBuPz,g

       add(2,3);

6fq1^n%}BSD愛好者樂園 [xNX9wqB X

       return 0;

4j g%Rv/[7Y_

oB TR;m1w}BSD愛好者樂園FWV]}-wEz

Sw'O$ofrg如果C++調(diào)用一個C語言編寫的.DLL時,,當(dāng)包 括.DLL的頭文件或聲明接口函數(shù)時,,應(yīng)加extern "C" { }。

-gx8}4x){W]BSD愛好者樂園+HF6_3}T

(2)在C中引用C++語言中的函數(shù)和變量 時,,C++的頭文件需添加extern "C",但是在C語言中不能直接引用聲明了extern "C"的該頭文件,,應(yīng)該僅將C文件中將C++中定義的extern "C"函數(shù)聲明為extern類型,。

.D!r0PI;\*k1u

b4kL d5`Z?O筆者編寫的C引用C++函數(shù)例子工程中包含的三個文件的源代碼如下:BSD愛好者樂園/x(n0e{EG#@

@$P#Hi@Zt+a//C++頭文件 cppExample.hBSD愛好者樂園"VYUz,s*X)R5R

E0X| q8R+L.tf#ifndef CPP_EXAMPLE_H

5Y8Y0]^9C#k,Em

/b|%Fl6O9OPx#define CPP_EXAMPLE_HBSD愛好者樂園-it D@E![E(C

$C7}[k_I Miextern "C" int add( int x, int y );BSD愛好者樂園6k7WH VR

UNOG%B8\x#endif

(AFV&?9}#X

N)t3^-^FRa3O//C++實現(xiàn)文件 cppExample.cpp

bW&C%^H'N@;PBSD愛好者樂園5w8c@2\/]Rt

#i nclude "cppExample.h"BSD愛好者樂園 J?_pk4x

R?Y2j*z?`int add( int x, int y )

3Fgb`QBSD 愛好者樂園6z%y"Ta@nN?v}T

{

nX8JxUr?Z&uBSD愛好者樂園ES!VP&n!gGO:eXr4j

       return x + y;

m.Y$P;pb5VLXf!IBSD愛好者樂園J3s][T ls

}BSD愛好者樂園 r*P KMoNen

Tj E;DEl/* C實現(xiàn)文件 cFile.c

5w!V,Su)n(W'q/N

}Q0w2?"UOU%x/* 這樣會編譯出錯:#i nclude "cExample.h" */

#f,{-NOU x6WBSD愛好者樂園9u&kw6Wu,f@G/c9L

extern int add( int x, int y );

$uB-{-dN[cUe`BSD愛好者樂園*~!q|V3}Gf

int main( int argc, char* argv[] )

$[n_ OW-IBSD愛好者樂園0~[OyD

{

YR8DqG"H%MP,J$zQ#D

zY,nJ-T       add( 2, 3 );   BSD愛好者樂園1j+x,n+O9b

BSD愛好者樂園}4ELA5emY

       return 0;BSD愛好者樂園L f/B%jM.t

BSD愛好者樂園&[a/uV2^E"g.q!p5O

}

~"~G(fk1a osW

[版權(quán)聲明]BSD愛好者樂園站內(nèi)文章,如來源不是互聯(lián)網(wǎng),,則均系原創(chuàng)或翻譯之作,,可隨意轉(zhuǎn)載,或以此為基礎(chǔ)進行演譯,,但務(wù) 必以鏈接形式注明原始出處和作者信息,,否則屬于侵權(quán)行為。另對本站轉(zhuǎn)載他處文章,,俱有說明,,如有侵權(quán)請聯(lián)系本人,本人將會在第一時間刪除侵權(quán)文章,。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多