From bf8b7ef7ffc5f750fc37c40ed1de020603976df6 Mon Sep 17 00:00:00 2001 From: light-city <455954986@qq.com> Date: Fri, 26 Jul 2019 15:13:47 +0800 Subject: [PATCH] update dir --- README.md | 1 + assert/README.md | 8 ++ bit/README.md | 6 +- extern/README.md | 193 ++++++++++++++++++++++++++++++++++++++ extern/extern_c++/add.c | 5 + extern/extern_c++/add.cpp | 9 ++ extern/extern_c++/add.h | 4 + extern/extern_c++/add.o | Bin 0 -> 1248 bytes extern/extern_c++/main | Bin 0 -> 8960 bytes extern/extern_c/add.c | 5 + extern/extern_c/add.cpp | 5 + extern/extern_c/add.h | 6 ++ extern/extern_c/add.o | Bin 0 -> 1248 bytes extern/extern_c/main | Bin 0 -> 8608 bytes volatile/README.md | 7 ++ 15 files changed, 246 insertions(+), 3 deletions(-) create mode 100644 extern/README.md create mode 100644 extern/extern_c++/add.c create mode 100644 extern/extern_c++/add.cpp create mode 100644 extern/extern_c++/add.h create mode 100644 extern/extern_c++/add.o create mode 100755 extern/extern_c++/main create mode 100644 extern/extern_c/add.c create mode 100644 extern/extern_c/add.cpp create mode 100644 extern/extern_c/add.h create mode 100644 extern/extern_c/add.o create mode 100755 extern/extern_c/main diff --git a/README.md b/README.md index b6a0de5..958cc51 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ - [x] [volatile那些事](./volatile) - [x] [assert那些事](./assert) - [x] [位域那些事](./bit) +- [x] [extern那些事](./extern) ## 关于作者: 个人公众号: diff --git a/assert/README.md b/assert/README.md index b935168..534fc49 100644 --- a/assert/README.md +++ b/assert/README.md @@ -1,5 +1,13 @@ # assert那些事 +## 关于作者: + +个人公众号: + +![](../img/wechat.jpg) + + + ## 1.第一个断言案例 断言,**是宏,而非函数**。assert 宏的原型定义在 (C)、(C++)中,其作用是如果它的条件返回错误,则终止程序执行。可以通过定义 NDEBUG 来关闭 assert,但是需要在源代码的开头,include 之前。 diff --git a/bit/README.md b/bit/README.md index b9514fa..69fd9ff 100644 --- a/bit/README.md +++ b/bit/README.md @@ -1,8 +1,8 @@ +## 关于作者: +个人公众号: -[TOC] - - +![](../img/wechat.jpg) ## Bit field 是什么? diff --git a/extern/README.md b/extern/README.md new file mode 100644 index 0000000..40d973c --- /dev/null +++ b/extern/README.md @@ -0,0 +1,193 @@ +# extern "C" + +## 关于作者: + +个人公众号: + +![](../img/wechat.jpg) + +## 1.C++与C编译区别 + +在C++中常在头文件见到extern "C"修饰函数,那有什么作用呢? 是用于C++链接在C语言模块中定义的函数。 + +C++虽然兼容C,但C++文件中函数编译后生成的符号与C语言生成的不同。因为C++支持函数重载,C++函数编译后生成的符时带有函数参数类型的信息,而C则没有。 + +例如`int add(int a, int b)`函数经过C++编译器生成.o文件后,`add`会变成形如`add_int_int`之类的, 而C的话则会是形如`_add`, 就是说:相同的函数,在C和C++中,编译后生成的符号不同。 + +这就导致一个问题:如果C++中使用C语言实现的函数,在编译链接的时候,会出错,提示找不到对应的符号。此时`extern "C"`就起作用了:告诉链接器去寻找`_add`这类的C语言符号,而不是经过C++修饰的符号。 + +## 2.C++调用C函数 + +C++调用C函数的例子: 引用C的头文件时,需要加`extern "C"` + +```c++ +//add.h +#ifndef ADD_H +#define ADD_H +int add(int x,int y); +#endif + +//add.c +#include "add.h" + +int add(int x,int y) { + return x+y; +} + +//add.cpp +#include +#include "add.h" +using namespace std; +int main() { + add(2,3); + return 0; +} +``` + +编译: + +``` +//Generate add.o file +gcc -c add.c +``` + +链接: + +``` +g++ add.cpp add.o -o main +``` + +没有添加extern "C" 报错: + +```c++ +> g++ add.cpp add.o -o main +add.o:在函数‘main’中: +add.cpp:(.text+0x0): `main'被多次定义 +/tmp/ccH65yQF.o:add.cpp:(.text+0x0):第一次在此定义 +/tmp/ccH65yQF.o:在函数‘main’中: +add.cpp:(.text+0xf):对‘add(int, int)’未定义的引用 +add.o:在函数‘main’中: +add.cpp:(.text+0xf):对‘add(int, int)’未定义的引用 +collect2: error: ld returned 1 exit status +``` + +添加extern "C"后: + +`add.cpp` + +```c++ +#include +using namespace std; +extern "C" { + #include "add.h" +} +int main() { + add(2,3); + return 0; +} +``` + +编译的时候一定要注意,先通过gcc生成中间文件add.o。 + +``` +gcc -c add.c +``` + +然后编译: + +``` +g++ add.cpp add.o -o main +``` + +上述案例源代码见: + +- [add.h](extern_c++/add.h) + +- [add.c](extern_c++/add.c) + +- [add.cpp](extern_c++/add.cpp) + +## 2.C中调用C++函数 + +`extern "C"`在C中是语法错误,需要放在C++头文件中。 + +```c +// add.h +#ifndef ADD_H +#define ADD_H +extern "C" { + int add(int x,int y); +} +#endif + +// add.cpp +#include "add.h" + +int add(int x,int y) { + return x+y; +} + +// add.c +extern int add(int x,int y); +int main() { + add(2,3); + return 0; +} +``` + +编译: + +```c +g++ -c add.cpp +``` + +链接: + +``` +gcc add.c add.o -o main +``` + +上述案例源代码见: + +- [add.h](extern_c/add.h) + +- [add.c](extern_c/add.c) + +- [add.cpp](extern_c/add.cpp) + +综上,总结出使用方法,在C语言的头文件中,对其外部函数只能指定为extern类型,C语言中不支持extern "C"声明,在.c文件中包含了extern "C"时会出现编译语法错误。所以使用extern "C"全部都放在于cpp程序相关文件或其头文件中。 + +总结出如下形式: + +(1)C++调用C函数: + +```c++ +//xx.h +extern int add(...) + +//xx.c +int add(){ + +} + +//xx.cpp +extern "C" { + #include "xx.h" +} +``` + +(2)C调用C++函数 + +```c +//xx.h +extern "C"{ + int add(); +} +//xx.cpp +int add(){ + +} +//xx.c +extern int add(); +``` + diff --git a/extern/extern_c++/add.c b/extern/extern_c++/add.c new file mode 100644 index 0000000..b347468 --- /dev/null +++ b/extern/extern_c++/add.c @@ -0,0 +1,5 @@ +#include "add.h" + +int add(int x,int y) { + return x+y; +} diff --git a/extern/extern_c++/add.cpp b/extern/extern_c++/add.cpp new file mode 100644 index 0000000..8ed76fa --- /dev/null +++ b/extern/extern_c++/add.cpp @@ -0,0 +1,9 @@ +#include +using namespace std; +extern "C" { + #include "add.h" +} +int main() { + add(2,3); + return 0; +} diff --git a/extern/extern_c++/add.h b/extern/extern_c++/add.h new file mode 100644 index 0000000..6984cdf --- /dev/null +++ b/extern/extern_c++/add.h @@ -0,0 +1,4 @@ +#ifndef ADD_H +#define ADD_H +extern int add(int x,int y); +#endif diff --git a/extern/extern_c++/add.o b/extern/extern_c++/add.o new file mode 100644 index 0000000000000000000000000000000000000000..4c8c0166688e71a05f7f34c991ae4669b52a5660 GIT binary patch literal 1248 zcmbtT%}T>S5S}#kw<=XU2=x$8D(I3(4eCKEr79u{VvZtd8xgcEG+R(Xy$RKekKiNt z4qkfn=nMD&-g*#prrEXY8ZSDK{bs(MZ)f%=*M;r%gkgX*16H9MNfy9Lbp2e%%|QzK z!P{)UHZR|sjrN`QephH4&j(Mik=AnN(8 z$I|1$83$JOxeu%uhQLa-N+qZwSFQ1YZR~jSA@@rs!0N%N&w}H_qq<)SM5X^h2IX`I z`bp%(vS0fYvHtd^kS9(*`F)YEgRY;(1bQET)z6`p*0k|cP1bi+5`9@;;-bQ-skdsN z_);gSEp&+ccGno+i-aYC67+wefD`oEaxy{SqbM{X;sHduBdM4CD02GQk)$Q`@*IdG i)BBI>o$^{VpuI!@gNRgHuTOo&)qfC$QbI35um1^?FiF+` literal 0 HcmV?d00001 diff --git a/extern/extern_c++/main b/extern/extern_c++/main new file mode 100755 index 0000000000000000000000000000000000000000..451dd010f25752b80536895e8fcedd4f53e1729b GIT binary patch literal 8960 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 literal 0 HcmV?d00001 diff --git a/extern/extern_c/main b/extern/extern_c/main new file mode 100755 index 0000000000000000000000000000000000000000..f026f11a1bf6d3141b9b93812b53981122ec3df5 GIT binary patch literal 8608 zcmeHNU2Ggz6~4RczckKzohGgG0~xi6S$J+aU>G1S>c)$j`@Nrj5+s@`bI}Y#fx|iNF*D?M3+1l zIr$PDxnakseL;2dLbX9^$PRx(NqE|ZEG@`NJ29< znMx{+B@XoVggdR>`fhy>A~_e)x&AFw0 zrst~p#vOZeA=-M5*04hi&O7-}eennDH6gN%0{|{1QP|+s>N8MzK9rfRXnrbepU76f z_kG|B!9E~Beqr#PlfY2>RhnK`Xv~*rkfr0`JXvzz`Y4xOIXm#t+3pq30x}n>ADs<- zCG=z{mk$kuBE9E!-Kx{jnR6|~kM`tl_vGH}edva~Mspwgmiq4G^XBvK+gjV7x&OVn zcYAZUyAUD2>AE>H?=knjmwlHm;MWF2PlpCW$3oWpY%$}9xUMpuy2KvL63;f@<3W^6 zb7nhI&`9@!N5I4A-A}=v2LCPiv*0(uZ-TdDBGG+Cd*U_7`F&?BqWSe~omp zJOY=n9weGoTnaex8kKpyGR*o6+1jAw(^ys#@ph5-SKFjk2;LvbwE}caSk4jAI)RAo z|Gtw?k$ll>5G(HaR6bf85nc8g#Kb-FjQynIv=1O^a+uhxI5S!tO2TrLh}R74&+8&u zIuhOQFfpa_vwld)TsPyf36R7xmL;-3hVsX9P0AkSx2)u#vMcrfo$)@_o#^Ua>NwEZ z`30?cU^tt!v)UfLU2kpa$V#d0+ie|sYrEdo_K;)HcDJ^5w05-ab;owgKFqG5*Kn(` zKlB#%%cVviEOtfzs=|CJ_pdI@lX5*~QH6f`M6IZF9ekLbeErJftP?{OZO2`g(DxVw??Pp`zYjcu!Lvr$O+2SgsFl+L27s~Y;#X?2@dkgPR%KbML z?&os-W;_zTs!_P;l#OWjs zihs!!|BUoseO-P8eWiZ= zoj3}80Kaeg7fQJzL?qCjj@^|<5b>&a*m5BIv{&&!8Qd53< z8+xkW9p|5S@&5(%8%2fZ=SbSl*xAuheFU%V4tDliy*)=GmL+2GbbKt4vEymWp0q|L zQptD*9gj}6iABDtgbMFat!`6AGrRhQb)dH|9O||D_U}L19kC*zaBnwdkncA~GFjOPVf91~ zS;gUr9O|UOiA0Ad;#8xs;<2b5WmxgGs9}`82*pss%Xvo%-?A5`uw_!#cr+P9NUNt0 zUa>^d%4Xt-UaW??1bH}qdEHPY4;Yot*S4&9p=YKi?dUML zop$&*w-QOrgyTX_rtG*L3iq_w(J>{BCA0c)Hi1{#iI~ty8johig&vzuBA&zTv|~9D zPiGRTWSL;WmX1$E37}fXCv2h1?&)aiV=0JsddYVq z!R@b)zzu1llZg@3kg_Q}G<3amjHA#omnShl%Wt;-L89L?+;WBIC9l)?yA7|~IW+l} z(t{9caq#mt;x!-@zl&&6DxUZ`#hNxWO7XnzvsJ*I?5MaK-v#|`tgSi!MXw<}FDeDs zuRgaF_8-y-r^7gCFTwcBUIP;CJ0ugP!{obK>brX%@FaA!*I>Nx8IV9~0}^zk!r483 z$6%qo0^@mI8dUfih2;9#kNGpO)82z+L*+LVUQ>9AQ(C`L%k>70DdUF}en{b)lq2VN z_y08Pgbyn}-ak!Mz*8(Y{ycP47x$Cb&9e&6zb`7h%*AcuIUJ>UUSD5w^`9~P9f$b^ z7oOMQ3kuKmGTtq}`tx^4{yzCcX)?4K$LcFCJnttKRQ^q_{=3KT*TB=KS2bLPeFuN9 zbo;yIH-T*^!Si~$iGqUM{%-lN@SzepKkoyyPl{=lRX~c^+JJ z<>!6T3Uvy^{*F|XS^p0hO6xD|pHu>kfr>MZ`HBnA>rzeOxlRtlIF|3AK|1a~uk%_J z(Cx2=gW5i|e* literal 0 HcmV?d00001 diff --git a/volatile/README.md b/volatile/README.md index f4dbcde..1090d42 100644 --- a/volatile/README.md +++ b/volatile/README.md @@ -1,4 +1,11 @@ +## 关于作者: + +个人公众号: + +![](../img/wechat.jpg) + ## 1.volatile + 被 `volatile` 修饰的变量,在对其进行读写操作时,会引发一些**可观测的副作用**。而这些可观测的副作用,是由**程序之外的因素决定的**。 ## 2.volatile应用