zz 關於external "C"的文章

EXTERNAL C的用法
2009-03-12 08:22:08
例:

兩個文件:

c文件:C.c

cpp文件:CPP.cpp

 

在討論extern "C"之前先來討論extern。

1、C/C++裏全局變量和全局函數的定義缺省是extern的。即如果一個project由好幾個文件組成,那麼在A文件的全局作用域中定義了全局變量或者全局函數,默認情況下在其他文件中是可見的,即其他的文件只要在自己的全局作用域中用extern顯式聲明A中的全局變量和函數,就可以使用A中定義的全局變量和全局函數。

2、需要注意的一點是,extern int external 這樣的聲明並不爲external分配內存空間。這裏只是一個聲明,它告訴編譯器 external 這個變量是在其他文件中定義。因此,在編譯的時候即使找不到external的定義也不會報錯,因爲連接的時候會在其他文件的obj中找到external。

3、cout<<"the value of external in c file is: "<<external<<endl;
   external=10;
   cout<<"after modified in cpp is : "<<func()<<endl;

用這三句代碼來說明extern:變量external是在C.c文件中定義的,CPP.cpp只是聲明瞭一下,它告訴編譯器CPP中用到的external是在別的文件中定義的。

首先,打印出external的值,爲5(C文件中定義externl爲5,這更加說明了CPP中並不爲external開闢新空間,否則應該爲0),

然後,在CPP文件中將external改爲10,通過調用func()顯式external的值。func()是C中的函數,它返回external的值,結果打印出10(進一步說明了external定義在C,使用在CPP)。

4、聲明的時候,如果去掉變量前面的extern,將會出現連接錯誤,提示定義了兩個同名變量。

5、與extern對應的是static。在全局作用域裏用static顯式聲明的變量和函數說明它們只能供其所在的文件使用,其他文件對其不可見;如果是在模塊中聲明一個static變量,則這個變量的作用域還是所在模塊,但是生命週期延長到程序結束。

再來看extern "C"

extern "C" 的引用就是爲了解決C++語言和C語言的混合編程問題。

C++支持的函數重載機制導致了C和C++編譯機制的不同。

1,比如對一個函數

                        void foo( int x, int y );

由C編譯器編譯後符號庫中的名字爲_foo;而C++編譯器編譯後則爲_foo_int_int,稱爲mangled name。C++正是靠這種編譯機制實現了重載,比如另有一個重載函數void foo( int x, floaty );則編譯後符號庫中的名字爲_foo_int_float。

這樣就容易理解了,一個用C編寫和編譯的函數,如果需要在一個C++程序中調用和使用它,必須用extern "C",因爲extern "C"能夠保證對調用的C函數採用C的方式對其進行編譯;否則,由於編譯後符號庫的名字不匹配,連接器在C的obj中找不到匹配的函數,則出現連接錯誤。

2,值得注意的是:不僅僅是全局函數,使用C中定義的全局變量也要放在extern "C"的{}中。

3,extern "C"中也可以添加整個C的頭文件(#include)。

4,由於C不支持extern "C",所以出現了源文件中的條件編譯語句(#ifdef...#endif)。

查看obj文件中符號庫的方法:

vc安裝目錄的bin目錄下有個應用程序dumpbin.exe。用如下命令行語句:

dumpbin.exe filename.obj /symbols /out:show.txt     ( /out:show.txt 是將輸出結果重定向到show.txt文件)

文章出處:(http://www.diybl.com/course/3_program/c++/cppjs/20091125/183420.html

 

dumpbin命令問題的解決辦法
http://www.cnblogs.com/neuqustciim/archive/2009/01/13/1374989.html
我們在查看一個.exe文件需要哪些.dll和一個dll會導出那些函數的時候我們都會用到dumpbin

我運行的時候dumpbin的時候總是提示dumbin是無效的命令(在DOS下的cmd命令中),按照孫鑫的視頻中的方法:

說找不到是可能是環境變量遭到破壞,運行D:/Program Files/Microsoft Visual Studio 8/VC/bin/vcvars32.bat,這個批處理程序就是爲VC設置環境變量的工具。但是好像我運行之後還是沒有用。我直接進到D:/Program Files/Microsoft Visual Studio 8/VC/bin看到了dumpbin.exe,但是就是在這個目錄下運行dumpbin也會提示找不到mspdb80.dll,當我把mspdb80.dll加到D:/Program Files/Microsoft Visual Studio 8/VC/bin下的時候是可以解決問題,但是這樣做的話下次啓動VS2005運行一個工程的話會出問題,會提示你fatal error C1902: 程序數據庫管理器不匹配;請檢查安裝,上網查了一下就是因爲我從common7 下把mspdb80.dll拷貝到bin下,但是沒有及時刪除造成的。可以參考http://topic.csdn.net/u/20071112/12/f2e5e61c-a591-4706-81b3-972f938b00af.html

看來dumpbin.exe的運行是依賴於mspdb80.dll,但是我們把mspdb80.dll從common7下移動到vc/bin下面又會造成VS的運行錯誤。我們知道一個.exe找.dll的順序是1)進程的當前目錄 2)windows目錄下的系統目錄是c:/windows/system32/目錄這個吧 3)Windows目錄 4)PATH環境變量中列出的目錄。看來是不能有兩個mspdb80.dll那我就讓dumpbin.exe運行的時候自己去找common7下的mspdb80.dll不就OK了。

步驟一:

在環境變量中的PATH變量中添加D:/Program Files/Microsoft Visual Studio 8/VC/bin;D:/Program Files/Microsoft Visual Studio 8/Common7/IDE路徑

這下子在D:/Program Files/Microsoft Visual Studio 8/VC/bin下運行dumpbin.exe沒有問題了,而且解決了VS2005啓動時的錯誤問題,但是我們想在當前的工程的目錄下來看.dll的屬性。而不像把.dll拷到VC/bin下面去看,如何解決?還是用環境變量PATH中添加路徑運行vcvars32.bat或是手動加上D:/Program Files/Microsoft Visual Studio 8/VC/bin應該都可以,後來我又沒有自己手動加上這一路徑

步驟二:

運行vcvars32.bat或手動加上D:/Program Files/Microsoft Visual Studio 8/VC/bin

這樣運行再運行dumpbin命令就OK了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章