• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            那誰的技術博客

            感興趣領域:高性能服務器編程,存儲,算法,Linux內核
            隨筆 - 210, 文章 - 0, 評論 - 1183, 引用 - 0
            數據加載中……

            探索C++的秘密之一詳解extern "C"

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

            #ifdef __cplusplus
            extern "C" {
            #endif

            //一段代碼

            #ifdef __cplusplus
            }

            #endif


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

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

                     比如下面的一段簡單的函數,我們看看加入和不加入extern "C"產生的匯編代碼都有哪些變化:

            int f(void)
            {
                
            return 1;
            }


                   在加入extern "C"的時候產生的匯編代碼是:

                .file    "test.cxx"
                .text
                .align 
            2
            .globl _f
                .def    _f;    .scl    
            2;    .type    32;    .endef
            _f:
                pushl    
            %ebp
                movl    
            %esp, %ebp
                movl    $
            1%eax
                popl    
            %ebp
                ret


            但是不加入了extern "C"之后

             .file "test.cxx"
             .text
             .align 
            2
            .globl __Z1fv
             .def __Z1fv; .scl 
            2; .type 32; .endef
            __Z1fv:
             pushl 
            %ebp
             movl 
            %esp, %ebp
             movl $
            1%eax
             popl 
            %ebp
             ret


                    兩段匯編代碼同樣都是使用gcc -S命令產生的,所有的地方都是一樣的,
            唯獨是產生的函數名,一個是_f,一個是__Z1fv.

                    OK,明白了加入與不加入extern "C"之后對函數名稱產生的影響,我們繼續我們的討論:為什么需要使用extern "C"呢?
                    C++之父在設計C++之時,考慮到當時已經存在了大量的C代碼,為了支持原來的C代碼和已經寫好C庫,需要在C++中盡可能的支持C,而extern "C"就是其中的一個策略.

                   試想這樣的情況:一個庫文件已經用C寫好了而且運行得很良好,這個時候我們需要使用這個庫文件,但是我們需要使用C++來寫這個新的代碼.如果這個代碼使用的是C++的方式鏈接這個C庫文件的話,那么就會出現鏈接錯誤.我們來看一段代碼:首先,我們使用C的處理方式來寫一個函數,也就是說假設這個函數當時是用C寫成的:

            //f1.c
            extern "C"
            {
            void f1()
            {
                
            return;
            }

            }

            編譯命令是:gcc -c f1.c -o f1.o   產生了一個叫f1.o的庫文件.
            再寫一段代碼調用這個f1函數:

            // test.cxx
            //這個extern表示f1函數在別的地方定義,這樣可以通過
            //編譯,但是鏈接的時候還是需要
            //鏈接上原來的庫文件.
            extern void f1();

            int main()
            {
                f1();

                
            return 0;
            }


            通過gcc -c  test.cxx -o test.o 產生一個叫test.o的文件.
            然后,我們使用gcc test.o f1.o來鏈接兩個文件,可是出錯了,錯誤的提示是:
            test.o(.text + 0x1f):test.cxx: undefine reference to 'f1()'
            也就是說,在編譯test.cxx的時候編譯器是使用C++的方式來處理f1()函數的,但是實際上鏈接的庫文件卻是用C的方式來處理函數的,所以就會出現鏈接過不去的錯誤:因為鏈接器找不到函數.
                  因此,為了在C++代碼中調用用C寫成的庫文件,就需要用extern "C"來告訴編譯器:這是一個用C寫成的庫文件,請用C的方式來鏈接它們.
                  比如,現在我們有了一個C庫文件,它的頭文件是f.h,產生的lib文件是f.lib,那么我們如果要在C++中使用這個庫文件,我們需要這樣寫:

            extern "C"
            {
            #include 
            "f.h"
            }

            回到上面的問題,如果要改正鏈接錯誤,我們需要這樣子改寫test.cxx:

            extern "C"
            {
            extern void f1();
            }


            int main()
            {
                f1();

                
            return 0;
            }


            重新編譯并且鏈接就可以過去了.

            總結:C和C++對函數的處理方式是不同的.extern "C"是使C++能夠調用C寫作的庫文件的一個手段,如果要對編譯器提示使用C的方式來處理函數的話,那么就要使用extern "C"來說明.

             

             

             

            posted on 2006-01-14 23:52 那誰 閱讀(4923) 評論(12)  編輯 收藏 引用 所屬分類: C\C++

            評論

            # re: 探索C++的秘密之一詳解extern "C"  回復  更多評論   

            寫得不錯。

            C++因為函數有很多種,成員函數拉,template函數拉,所以他會對函數名稱進行變換。
            C很單純,一般也就是在函數名稱前面加上一個_就好了。
            2006-01-16 10:06 | 小明

            # re: 探索C++的秘密之一詳解extern "C"  回復  更多評論   

            學習哈:)
            2006-01-16 17:37 | uestc

            # re: 探索C++的秘密之一詳解extern "C"  回復  更多評論   

            extern "C"是使C++能夠調用C寫作的庫文件的一個手段
            --------------
            同樣,extern "C"也是使C能夠調用C++庫文件的一個手段。只不過,C不能直接包含帶extern "C"的C++頭文件,需要用extern聲明一下要使用的函數。
            2006-01-19 17:21 | 力為

            # re: 探索C++的秘密之一詳解extern "C"  回復  更多評論   

            不同編譯器處理這種修飾名的方法是不同的,這就是為什么有些人不喜歡發布類庫的原因,換個編譯器,就只能重新編譯了。
            2006-01-22 16:38 | feelapi

            # re: 探索C++的秘密之一詳解extern "C"  回復  更多評論   

            總結一句話:就是為了方便在C++程序中調用C程序
            2006-01-24 17:00 | 流氓

            # re: 探索C++的秘密之一詳解extern "C"  回復  更多評論   

            這篇好像完整點
            http://blog.csdn.net/billyang1983/archive/2006/01/04/570498.aspx
            2006-02-25 01:43 | Kemin

            # re: 探索C++的秘密之一詳解extern "C"  回復  更多評論   

            寫的亂七八糟的,
            2006-04-08 14:01 |

            # re: 探索C++的秘密之一詳解extern "C"  回復  更多評論   

            這篇寫的最好最全
            http://blog.csdn.net/keensword/archive/2005/06/23/401114.aspx
            2006-05-12 14:21 | mem

            # re: 探索C++的秘密之一詳解extern "C"  回復  更多評論   

            你好,我們是一家致力于中國互聯網的本地搜索、手機地圖和位置服務的創業型軟件公司。入選2005年最值得關注的50家商業網站(www.mapabc.com)。Google、Sina、微軟、中搜、阿里巴巴、中國移動等著名的公司都是圖盟科技的合作伙伴,因業務需要,需要招聘一些對于C++方面比較熟悉的人,我看了你的blog,希望和你交流一下,如果你有意在北京工作,而且愿意從事一些有挑戰性的工作的話,請將簡歷發送到hyla_he@126.com,我會與你聯系,謝謝
            2006-07-05 13:04 | hyla

            # re: 探索C++的秘密之一詳解extern "C"  回復  更多評論   

            嗷嗷,抱歉,一年前剛剛離開北京現在在深圳,哈~~
            2006-07-05 17:34 | 創系

            # re: 探索C++的秘密之一詳解extern "C"  回復  更多評論   

            @力為


            編寫C/C++公用的用extern "C"頭文件也是可以的。
            #ifdef __cplusplus
            /*
            C++專用部分,包括 class聲明, 公共函數的重載等。
            */
            extern "C" {
            #endif /*__cplusplus*/
            /*
            C / C++ 公共部分,包括結構聲明,函數聲明,變量聲明。
            */

            #ifdef __cplusplus
            }
            #endif /*__cplusplus*/
            2006-08-22 17:27 | yihao

            # re: 探索C++的秘密之一詳解extern "C"  回復  更多評論   

            http://donna-matura-zoccola.fatte-tun.info
            http://dvd-de-cul.culs-ugx.info
            http://scopare-cinese-foto.sculaccia-tun.info
            http://elle-suce-son-gendre.succhiano-ugx.info
            http://brazil-fetish-video.sculaccia-tun.info
            http://baise-amatrice.senegalese-ugx.info
            http://coppia-trans-escort-romagna.fatte-tun.info
            http://video-de-sexe-gratuitement.succhiano-ugx.info
            http://pokemon-porno.sculaccia-tun.info
            http://video-sexe-amateur-gratuit.senegalese-ugx.info
            http://ciccione-scopano.sculaccia-tun.info
            http://sexe-amateur-francais.succhiano-ugx.info
            http://eva-henger-gratis-porno-video.gradis-tun.info
            http://france-sexe-gratuit.culs-ugx.info
            http://arrapanti-casalinghe.sculaccia-tun.info
            http://telechargement-gratuit-video-sexe-gratuite.senegalese-ugx.info
            http://intervista-gay-escort.sculaccia-tun.info
            http://gratuit-porno-pute-video.senegalese-ugx.info
            http://fotoracconti-erotici-amatoriali.sculaccia-tun.info
            http://rencontre-sexe-en-moselle.senegalese-ugx.info
            http://racconto-o-storia-porno.gradis-tun.info
            http://bresilienne-qui-baise.culs-ugx.info
            http://foto-orgia-tettona.fatte-tun.info
            http://karine-sexe.culs-ugx.info
            http://video-bella-donna-scopata.fatte-tun.info
            http://sexe-moselle.culs-ugx.info
            http://foto-sesso-vecchio-gratis.gradis-tun.info
            http://mangas-land-sexe-gratuit.succhiano-ugx.info
            http://sakura-sexy-gratis.fatte-tun.info
            http://suce-bite-.com.succhiano-ugx.info
            http://sborra-gola.sculaccia-tun.info
            http://over-blog-sexe-mature.culs-ugx.info
            http://bocchino-hard.fatte-tun.info
            http://la-salope-du-jour.succhiano-ugx.info
            http://hard-core-video-amatoriale.fatte-tun.info
            2007-12-30 08:49 | sdgsdg
            麻豆精品久久久一区二区| 日韩精品久久久久久免费| 久久久人妻精品无码一区 | 久久人人爽人人爽人人片AV不| 成人久久免费网站| 日韩欧美亚洲综合久久影院d3| 久久www免费人成看国产片| 欧美精品乱码99久久蜜桃| 久久精品草草草| 精品国产乱码久久久久久人妻| 亚洲国产精品久久| 伊人久久大香线蕉亚洲五月天| 岛国搬运www久久| 亚洲国产精品无码久久久蜜芽| 99久久精品国产一区二区| 亚洲熟妇无码另类久久久| 久久国产精品二国产精品| 久久w5ww成w人免费| 免费无码国产欧美久久18| 久久久国产精华液| 精品一区二区久久| 天天爽天天狠久久久综合麻豆| 久久久久久av无码免费看大片| 久久福利青草精品资源站免费| 亚洲国产美女精品久久久久∴| 三级片免费观看久久| 国内精品伊人久久久久网站| 久久精品国产久精国产| 久久99精品久久久久久hb无码| 偷窥少妇久久久久久久久| 久久中文精品无码中文字幕| 国产成人精品久久综合| 成人国内精品久久久久影院VR| 国内精品人妻无码久久久影院| 波多野结衣AV无码久久一区| 国内精品伊人久久久久777| 亚洲精品NV久久久久久久久久| 久久五月精品中文字幕| 亚洲国产成人乱码精品女人久久久不卡 | 日本精品一区二区久久久| 国产视频久久|