c++dll生成和调用
轉載:http://hi.baidu.com/new_day2009/blog/item/51e0c6ec1cd05adbb21cb16d.html
生成Dll文件
新建項目,選擇Win32項目,工程名:09DllDemo 確定后,選擇應用程序設置, 應用程序類型選擇DLL(D),附加選項上選擇 導出符號(X)(便于學習)。單擊完成,完成工程創建。
-----------------------------------------------------------------------------------------------------------------
打開 09DllDemo.cpp文件,因為選擇導出符號的緣故,VC++自動給我們生成了
// 這是導出函數的一個示例。
extern "C"
{
// 這是導出函數的一個示例。
MY09DLLDEMO_API int fnMy09DllDemo()
{
?? return 42;
}
}
打開 09DllDemo.h 我們可以看到聲明的函數。
//聲明要導出的函數
extern "C"
{
MY09DLLDEMO_API int fnMy09DllDemo();
}
---------------------------------------------------------------------------------------------------------------------
我們自己要添加入的函數按上述格式添加就可以了。(加extern "C"能保證導出的Dll函數名不會變化。這里的描述可能有點問題)
選中項目,點生成,生成Dll文件的任務就完成了。最后09DllDemo工程產生的文件中有3個可以被其他工程所使用:09DllDemo.h 09DllDemo.dll 09DllDemo.lib。
.dll文件就是動態鏈接庫,.lib是供程序開發用的導入庫,.h文件包含了導出函數的聲明。
調用Dll文件
調用Dll中的導出函數有兩種方法:
1.裝載期間動態加載。
模塊可像調用本地函數一樣調用從其他模板導出的函數(API函數就是這樣調用的)。裝載期間鏈結必須使用DLL的導入庫(.lib)文件,它為系統提供了加載這個Dll和定位Dll中的導出函數所需的信息。
應用程序啟動時由載入器(加載應用程序的組件)載入09DllDemo.dll文件。載入器如何知道要載入哪些Dll呢?這些信息記錄在執行文件(PE文件)的idata節中。使用這種方法不用自己寫代碼顯式加載DLL。
---------------------------
新建一個09ImportDemo的Win32控制臺工程,將09DllDemo.h,09DllDemo.lib,09DllDemo.dll 3個文件拷貝到09ImportDemo目錄下。
下面給出了調用導出函數fnMy09DllDemo的代碼
#include "09DllDemo.h"
#include <iostream>
using namespace std;
#pragma comment(lib,"09DllDemo")
void main()
{
int a =fnMy09DllDemo();
cout<<a<<endl;
}
發布軟件時必須將該軟件使用的Dll與主程序一起發布。09ImportDemo.exe和09DllDemo.dll放在同一個目錄下。載入器加載Dll文件時,默認情況是在應用程序的當前目錄下查找,如果找不到就到系統盤"\windows\system32"文件夾下查找,還找不到就按錯誤處理。
--------------------------------------------------------------------------------------------------------------
2.運行期間動態加載。(只需Dll文件即可)
運行期間動態加載是在程序運行過程中顯式得加載Dll庫,從中導出需要的函數。
為了能夠在運行期間動態導出函數,一般需要在09DllDemo工程中建立一個DEF文件來指定要導出的函數。
----添加DEF文件
打開09DllDemo工程,右鍵點擊工程,選擇添加,選擇TextFile選項,輸入文件名DllDemo.def
新的DllDemo.def中添加如果內容
=============================
EXPORTS
??????? fnMy09DllDemo
=============================
重新生成下就完成了。
回到09ImportDemo工程,將程序修改為
------------------------------------------------------------------------------------------
#include <windows.h>
#include <iostream>
using namespace std;
//定義FunctionFunc為指向一個返回值為int型 無參數的函數的指針
typedef int (*FunctionFunc)();
int main()
{
?? FunctionFunc _FunctionFunc;
?? //加載目標Dll
?? HMODULE hModule = ::LoadLibrary(TEXT("D:\\09DllDemo.dll"));
?? if (hModule==NULL)//如果Dll加載失敗,釋放它占用的資源
?? {
??? ::FreeLibrary(hModule);
?? }
?? //取得目標Dll中導出函數的地址(提醒:函數名就是函數的入口地址)
?? _FunctionFunc=(FunctionFunc)::GetProcAddress(hModule,"fnMy09DllDemo");
?? if (_FunctionFunc==NULL)
?? {
??? ::FreeLibrary(hModule);
?? }
?? int a =_FunctionFunc();
?? cout<< a<<endl;
?? ::FreeLibrary(hModule);
?? cin.get();
?? return 1;
}
------------------------------------------------------------------------------------------
c#中調用Dll
[DllImport("D:\\09DllDemo.dll")")]
??????? public static extern int fnMy09DllDemo();
------------------------------------------------------------------------------------------
備注:
在沒加extern "C"生成的Dll的函數名會有變化,因此在運行期間動態鏈結過程中,調用GetProcAddress會返回空值。
如不能修改Dll源碼,可采用下面的方式解決(比較笨的方法,有好的請留言,謝謝):先用Depends.Exe(VS自帶的工具)打開Dll文件,右鍵點擊函數復制函數名。如獲得的函數名為
?fnMy09DllDemo@@YAHXZ
C++中 直接
_FunctionFunc=(FunctionFunc)::GetProcAddress(hModule,?fnMy09DllDemo@@YAHXZ);
c#中
[DllImport("D:\\09DllDemo.dll", EntryPoint = "?fnMy09DllDemo@@YAHXZ")]
public static extern int fnMy09DllDemo();
總結
以上是生活随笔為你收集整理的c++dll生成和调用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c++调用Java以及string互转
- 下一篇: jni详解