vc與dev-c++混合編程 動態鏈接庫c函數調用

上回書說道,如何在vc中使用dev-c++中的類,這次說一個更簡單的問題,如何實現vc調用dev-c++的函數。

1、打開dev-c++,新建工程,選擇dll,輸入工程名testdll,選擇c工程,完成後,模板工程生成了兩個文件,dll.h 和 dllmain.c,先進行編譯,生成libtestdll.a和testdll.dll。

#ifndef _DLL_H_
#define _DLL_H_

#if BUILDING_DLL
# define DLLIMPORT __declspec (dllexport)
#else /* Not BUILDING_DLL */
# define DLLIMPORT __declspec (dllimport)
#endif /* Not BUILDING_DLL */


DLLIMPORT void HelloWorld (void);


#endif /* _DLL_H_ */

2、打開vs2010,當然vc6、vs2005、vs2008也應該一樣。新建一個對話框工程,在對話框設計圖上雙擊“OK”按鈕,生成“OK”響應代碼,手工添加代碼“HelloWorld();”。在stdafx.h中,添加:#include “dll.h”,然後設置工程屬性,主要是設置包含路徑和庫路徑。(Dev-c++缺省把所有東西都放到同一個目錄裏了)。只是使用F7生成,編譯應該沒有問題,鏈接時會出現TestPrjDlg.obj : error LNK2019: 無法解析的外部符號 "__declspec(dllimport) void __cdecl HelloWorld(void)" (__imp_?HelloWorld@@YAXXZ),該符號在函數 "public: void __thiscall CTestPrjDlg::OnBnClickedOk(void)" (?OnBnClickedOk@CTestPrjDlg@@QAEXXZ) 中被引用
1>../TestDll/TestPrj.exe : fatal error LNK1120: 1 個無法解析的外部命令。

 

下面,我們一步步的來修改vc工程與dev-c++工程,使得vc程序能夠調用dev-c++的dll庫。

1、修改dll.h,如下所示,(藍色爲添加部分),修改以後重新生成。

#if BUILDING_DLL
# define DLLIMPORT __declspec (dllexport) __stdcall
#else /* Not BUILDING_DLL */
# define DLLIMPORT extern "C" __declspec (dllimport)
#endif /* Not BUILDING_DLL */

 2、生成lib文件,(.a文件與.lib文件格式是不同的,但是在vs2010中,附件庫直接採用.a我也成功過)。

第一種辦法:採用vs的lib.exe工具生成lib。首先,打開libtestdll.def,在exports前輸入:LIBRARY “TestDll”,然後在命令行中進入 testdll目錄,執行如下命令:

lib   /machine:i386   /def:libtestdll.def

將會生成libtestdll.lib文件。這裏的Library主要是指要鏈接到的庫,如果不加這行,默認爲libtestdll.dll,最後在運行testprj.exe時會提示找不到libtestdll.dll庫。

第二種辦法,使用dumpbin.exe工具生成.def文件,這個稍微麻煩一些,也是在命令行下輸入:

DUMPBIN testdll.dll /EXPORTS /OUT:libtestdll.def

生成後,裏面的行數比較多,手工將輸出函數之外的內容全部刪除,然後,同上,手工添加:Library等。

最後,在vs2010的工程附加庫中指定libtestdll.lib,去除最初使用的libtestdll.a文件。

3、修改testprj工程屬性,函數調用方式爲:stdcall (缺省爲 cdecl)。

4、重新生成testprj工程,運行後點擊OK,彈出“Hello World From Dll!”,是不是成功了呢?

5、再給HelloWorld()函數添加兩個參數,試試,一樣成功,完美了!

 

說明:轉來的那篇文章裏,說的是在vc下,如何採用顯示調用的方式,也就是通過LoadLibrary()和GetProcessAddress()來實現,我在嘗試的過程中,如果函數沒有參數,還不會有問題,有參數時,老是會出現堆棧平衡的問題,也就是那個檢查esp的問題。

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