動態庫的建立和呼叫

weixin_34104341發表於2020-04-07

VC++支援的DLL:

VC++支援三種DLL:

1非MFC動態庫

2MFC規則DLL

3MFC擴充套件DLL。

DLL匯出函式(或變數、類)可供應用程式呼叫;DLL內部函式只能在DLL程式內使用,應用程式無法呼叫它們。

 

匯出函式的宣告方式:

1一種在函式宣告型別和函式名之間加上“_declspec(dllexport)”。

2另外一種採用模組定義(.def)檔案宣告,需要在庫工程中新增模組檔案,格式如下:

  LIBRARY 庫工程名稱

  EXPORTS 匯出函式名

 

DLL的呼叫方式:

靜態呼叫中,由編譯系統完成對DLL的載入和應用程式結束時DLL的解除安裝。

動態呼叫中,由程式設計者用API函式載入和解除安裝DLL(DLL載入—DLL函式地址獲取—DLL釋放)方式。

例子

 建立動態連結庫(MFC規則DLL)

1. New--projects--MFC AppWizard(dll)--Regular DLL using shared MFC DLL

2. def檔案中新增:函式名(FunctionName)

3. h檔案中新增:外部函式宣告//求和函式,函式名為FunctionName

  extern "C" __declspec(dllexport) int __stdcall FunctionName();

4. cpp檔案中新增: 外部函式實現

  extern "C" __declspec(dllexport) int __stdcall FunctionName(int a,int b)

  {

    print("don something here");

  }

5. build--set active configuration--win32 release--ok

6. 生成

7. 根目錄下release資料夾中dll,lib與根目錄下h檔案即為所需

建立動態連結庫(非MFC DLL)

1. new---projects---win32 dynamic-link library----an empty project(Sample)

2. 新增sample.h

#ifndef SAMPLE_H

#define SAMPLE_H

extern int dllGlobalVar;

#endif

3. 新增 sample.cpp

#include "sample.h"

#include <windows.h>

int dllGlobalVar;

bool APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)

//windows在載入DLL時,需要一個入口函式,就如同控制檯或DOS程式需要main函式、win32程式需要winmain函式一樣。所以引入一個不做任何操作的預設DllMain的函式版本。是DLL的內部函式。

呼叫動態連結庫(把MFC_dll.dll和MFC_dll.lib拷到工程所在目錄)

//靜態呼叫(.h可以寫到.cpp檔案中)

1. new--projects--win32 console application--an empty project

2. 新增h檔案:(test.h)

#pragma comment(lib,"XXXX.lib") //告訴編譯器DLL相對應的lib檔案所在路徑和檔名

extern "C" _declspec(dllimport) int _stdcall FunctionName();//宣告匯入函式

3. 新增cpp檔案:(main.cpp)

#include "test.h"

int main()

{

cout<<Add_new(10,3);

return 0;

}

//動態呼叫

#include <stdio.h>

#include <windows.h>

typedef int (* lpTestFun)();//定義一個與FunctionName函式接受引數型別和返回值均相同的函式指標型別

int main()

{

  HINSTANCE hDll;//控制程式碼  

  lpTestFun theFun;//函式指標

  hDll=LoadLibrary("XXXX.dll");//動態載入DLL模組控制程式碼

  if(hDll)

  {

    theFun=(theFun) GetProcAddress(hDll,"FunctionName");//得到所載入DLL模組中函式的地址,函式名可以使用VS6.0的Dll檢視工具檢視

    if(theFun)

    {

      theFun();

      printf("%d",result); } FreeLibrary(hDll);//釋放已經載入的DLL模組

    }

    return 0;

}

 

有一點要注意,如果看到此類巨集定義
#ifdef KSCANBAR_EXPORTS
#define KSCANBAR_API __declspec(dllexport)
#else
#define KSCANBAR_API __declspec(dllimport)
#endif
是因為

這樣定義一般出現在含有多個專案的解決方案中,這樣可以使從 DLL 匯出更簡單的巨集的標準方法。此 DLL 中的所有檔案都是用命令列上定義的 KSCANBAR_EXPORTS符號編譯的。在使用此 DLL 的任何其他專案上不應定義此符號。這樣,原始檔中包含此檔案的任何其他專案都會將KSCANBAR_API 函式視為是從 DLL 匯入的,而此 DLL 則將用此巨集定義的符號視為是被匯出的。

參考 http://blog.csdn.net/crich_moon/article/details/6039939

轉載於:https://www.cnblogs.com/zerolu/p/4689434.html

相關文章