DLL宣告的總結

2021-05-02 18:09:44 字數 2806 閱讀 2465

本文**於:http://topic.csdn.net/u/20090824/13/be972397-bec9-4f7f-910c-83e0d91bcbad.html

有關dll的問題現在資料很多,但是很多人寫dll時經常出現呼叫程式無法找到相關的匯出函式的問題,這裡主要的原因是dll在宣告時出的問題。

在這裡主要有兩個問題,乙個是呼叫約定的問題,乙個是函式名修飾的問題,而這兩個問題又是相互影響的。

一:宣告為:extern "c" int __declspec(dllexport)add(int x, int y);

這種宣告是強制用c語言方式進行修飾,且用c的預設約定,即__cdecl方式。這種方式編譯產生的dll中有乙個匯出函式:add,不加任何修飾。

二:宣告為:extern "c" int __declspec(dllexport) __stdcall add(int x, int y);

這種宣告是強制用c語言方式進行修飾,且用stdcall約定,這種方式編譯產生的dll中有乙個匯出函式:_add@8,即前面有「_」,後面加了引數長。

三:宣告為:int __declspec(dllexport) __stdcall add(int x, int y);

這種宣告不強制用c語言方式進行修飾,但是用stdcall約定,這種方式編譯產生的dll中有乙個匯出函式:?add@@yghhh@z。這個名字很怪,後面的不好理解。

四:宣告為:int __declspec(dllexport) __cdecl add(int x, int y);

這種宣告是不強制用c語言修飾,且用cdecl約定,這種方式編譯產生的dll中有乙個匯出函式:?add@@yahhh@z,注意看,和第三種方有一點不同。

實驗一:顯式呼叫方式呼叫dll中的add函式。

#include

#include

typedef  int(_stdcall *lpaddfun)(int, int); //巨集定義函式指標型別

int main(int argc, char *argv)

else

printf("no function");

} else

printf("no dll");

freelibrary(hdll);

return 0;

} 方式一:呼叫成功。另外三種方式全部出錯

實驗二:隱式呼叫dll中的add函式

#include

#include

#pragma comment(lib,"1.lib")

extern "c" int __declspec(dllimport) add(int x, int y);//宣告方式隨著dll中的宣告方式改變

int main(int argc, char *argv)

方式一:呼叫成功。另外發現乙個奇怪現象:在呼叫程式中

宣告函式時extern "c" int __declspec(dllimport) add(int x, int y);

寫作:extern "c" int __declspec(dllecprot) add(int x, int y);同樣成功,將__declspec(…)去掉也同樣成功。換句話說,在呼叫dll的程式中,匯入是沒有必要加的。

方式二:呼叫成功。同樣出現上面匯入標識可以不加的現象。

方式三:呼叫成功,同樣也出現上面匯入標識可以不加的現象。

方式四:呼叫成功,同樣也出現上面匯入標識可以不加的現象。

總結:對於dll匯出函式宣告的四種寫法,在動態呼叫時,

宣告成這樣:extern "c" int __declspec(dllimport) add(int x, int y);是最好的,其它宣告方式呼叫都沒有成功。但是眾所周知,windows預設的呼叫約定是stdcall方式,如果想別的語言能用dll的話,最好是將呼叫約定寫成stdcall方式,但是這種方式又不能動態呼叫。

在隱式呼叫時,四種宣告方式都是可以的,只要呼叫者的宣告方式和dll宣告時的方式一致即可。另外,在呼叫程式中對於匯入的宣告是可以去掉的,大量書籍中關於匯入、匯出的問題都是利用巨集來處理的,如:在標頭檔案中寫作:

#ifdef dll_file

extern "c" int __declspec(dllexport) add(int x, int y);

#else

extern "c" int __declspec(dlleximport) add(int x, int y);

這樣這個標頭檔案既可以用在dll工程中,又可以用在呼叫程式中,但是經過實驗發現,這個根本就沒有必要,在呼叫者程式中不管是寫作__declspce(dllexport)還是寫作__declspec(dllimport)或者不寫都能成功呼叫。

關於def檔案

在dll工程中引用def檔案,內容如下:

library 1

exports

add @ 1

通過depends檢視匯出函式全是add,但是隱式方式呼叫時,還是要求呼叫者的宣告方式和dll中宣告方式相同。

對於動態呼叫實驗結果:

方式一:成功。方式二:不成功,但是將函式指標改為typedef int(_stdcall *lpaddfun)(int, int);成功,即呼叫者要宣告約定方式與dll中宣告的呼叫約定方式相同,否則報錯。

方式三:同方式二,同樣要將函式指標改為typedef int(_stdcall *lpaddfun)(int, int);才成功完成呼叫。

方式四:成功。

總結:通過def檔案來匯出函式,呼叫者同樣也要宣告相同的呼叫約定,即_stdcall或是_cdecl必須要相同,其中_cdecl是c語言預設方式。

Dll 匯出函式 引用Dll外部函式宣告

匯出函式 declspec dllexport int function 匯出類class declspec dllexport class1 引用dll函式宣告 declspec dllimport int function 解決不同編譯器名字改編的問題 在定義匯出函式時加上 extern c 大...

總結一下DLL宣告的一些問題

有關dll的問題現在資料很多,但是很多人寫dll時經常出現呼叫程式無法找到相關的匯出函式的問題,這裡主要的原因是dll在宣告時出的問題。在這裡主要有兩個問題,乙個是呼叫約定的問題,乙個是函式名修飾的問題,而這兩個問題又是相互影響的。一 宣告為 extern c int declspec dllexp...

DLL視窗的控制總結

1.dll子視窗的式樣必須設定為無框 borderstyle bsnone formstyle fsnormal 可以在dll.dpr中 控制 2.dll.dpr vardllscr tscreen varptr plongint begin screen scr frmdllform.top to...