天天看點

c++動态庫封裝及調用(VS2015)

c++動态庫封裝及調用(3、windows下動态庫調用)

1.DLL的隐式調用

隐式連結采用靜态加載的方式,比較簡單,需要.h、.lib、.dll三件套。建立“控制台應用程式”或“空項目”。配置如下: 

項目->屬性->配置屬性->VC++ 目錄-> 在“包含目錄”裡添加頭檔案testdll.h所在的目錄 

項目->屬性->配置屬性->VC++ 目錄-> 在“庫目錄”裡添加頭檔案testdll.lib所在的目錄 

項目->屬性->配置屬性->連結器->輸入-> 在“附加依賴項”裡添加“testdll.lib”(若有多個 lib 則以空格隔開) 。 //你也可以在代碼中添加一行設定庫的連結,#pragma comment(lib, "DLLSample.lib")

c++動态庫封裝及調用(VS2015)

庫檔案頭檔案等目錄設定,本文将庫檔案及頭檔案拷貝到工程目錄下DLL檔案夾下

c++動态庫封裝及調用(VS2015)
c++動态庫封裝及調用(VS2015)
c++動态庫封裝及調用(VS2015)

添加LIB依賴項

c++動态庫封裝及調用(VS2015)

 #調用的源程式#

// callmyDLL.cpp : 定義控制台應用程式的入口點。  
//包含頭頭檔案,函數聲明    
  
#include "stdafx.h"  
#include "stdlib.h"  
#include "myDLL.h"  
  
int _tmain(int argc, _TCHAR* argv[])  
{  
  //這是通過上節的extern方式調用的
    int z= Add(1,2);  
  
  //也可以通過類導出的方式調用
  //CmyDll dll;
  //int z = dll.Add(1,2);

    printf("z is:%d\n", z);  
    system("pause");  
    return 0;  
}        

以上如果包含目錄、庫目錄、庫的依賴項都沒有問題就可以生成成功了

#運作時最後一步:将動态庫檔案拷貝到可執行檔案目錄下,否則會出現如下錯誤。

c++動态庫封裝及調用(VS2015)
c++動态庫封裝及調用(VS2015)

如何沒有設定lib目錄和依賴項,可以在代碼中添加以下一行代碼也可以生成成功

// callmyDLL.cpp : 定義控制台應用程式的入口點。  
//包含頭頭檔案,函數聲明    
  
#include "stdafx.h"  
#include "stdlib.h"  
#include "myDLL.h"  
#prama comment(lib, "myDll.lib")  
//此時的myDll.lib的路徑必須能找到的,可以給定一個全路徑如:“c:\\myDll.lib”

int _tmain(int argc, _TCHAR* argv[])  
{  
    int z= Add(1,2);  
    printf("z is:%d\n", z);  
    system("pause");  
    return 0;  
}        

是以通過設定依賴項和庫目錄和添加#Prama是具有相同效果的,如果有問題,得檢查是否兩者的生成平台不同(如win32和x64)或者一個是Debug一個是release

2、DLL顯示調用

對于顯示連接配接,即動态加載我們需要調用LoadLibrary

在MSDN中:HMODULE WINAPI LoadLibrary(

  __in  LPCTSTR lpFileName

);

它的功能是映射一個可執行子產品到調用程序的位址空間。由此我們知道顯示調用就是函數指針來調用函數。

Steps:

1、聲明頭檔案<windows.h>,說明我想用windows32方法來加載和解除安裝DLL

2、然後用typedef定義一個指針函數類型.typedef  void(*fun) //這個指針類型,要和你調用的函數類型和參數保持一緻

3、定一個句柄執行個體,用來取DLL的執行個體位址。HINSTANCE hdll;

格式為hdll=LoadLibrary(“DLL位址”);這裡字元串類型是LPSTR,當是unicode字元集的時候會不行,

是以要在配置-屬性-正常裡面把預設字元集“unicode”改成支援多字元擴充即可。

4、取的位址要判斷,傳回的句柄是否為空,如果為無效句柄,那麼要釋放加載DLL所占用的記憶體。

5、定義一個函數指針,用來擷取你要用的函數位址。

  然後通過GetProcAdress來擷取函數的位址,參數是DLL的句柄和你要調用的函數名:比如:FUN=(fun)GetProcAdress(hdll,"sum");

  這裡也要判斷要函數指針是否為空,如果沒取到要求的函數,那麼要釋放句柄。

6、然後通過函數指針來調用函數。

7、調用結束後,就釋放句柄FreeLibrary(hdll);

直接上代碼,一一一一一目了然

// callDLLSee.cpp : 定義控制台應用程式的入口點。  
//通過調用windowsAPI 來加載和解除安裝DLL  
#include "stdafx.h"  
#include "Windows.h"  
typedef int(*Dllfun)(int , int);  
  
int _tmain(int argc, _TCHAR* argv[])  
{  
    Dllfun funName;  
    HINSTANCE hdll;  
    //put DLL under the Debug path   
    //use   _T 設定為寬字元  
    hdll = LoadLibrary( _T("myDLL.dll"));  
    if (hdll == NULL)  
    {  
        FreeLibrary(hdll);  
    }  
    funName = (Dllfun)GetProcAddress(hdll, "Add");  
    if (funName == NULL)  
    {  
        FreeLibrary(hdll);  
    }  
    int x = 1, y = 10;  
    double z= funName(r, h);  
    printf("z= %d\n", z);  
  
    FreeLibrary(hdll);  
    return 0;  
}