天天看點

DLL中導出函數的聲明有兩種方式

一種方式是:在函數聲明中加上__declspec(dllexport);

另外一種方式是:采用子產品定義(.def)檔案聲明,(.def)檔案為連結器提供了有關被連結程式的導出、屬性及其他方面的資訊。

方式一:在函數聲明中加上__declspec(dllexport)

/// 在動态連結庫程式中

/// 聲明動态連結庫(**.dll)的對外接口函數TestFuction

extern "C" __declspec(dllexport) int TestFuction(int nType,char *strPath,std::vector<string> &vecData)

{

   do anything here

   return 0;

}

/// 在外部希望調用動态連結庫的程式中

/// 加載動态連結庫(**.dll)并調用其對外接口TestFuction

void func()

{

  //typedef與函數TestFuction類型相同的函數指針為TESTDLL

  typedef int (_cdecl * TESTDLL)(int nType,char *strPath,std::vector<string> &vecData);

  HINSTANCE hmod;

  //加載動态連結庫**.dll

  hmod =::LoadLibrary(_TEXT("dll相對路徑\\**.dll"));

  if(NULL == hmod)

  {

     TRACE("加載**.dll失敗");

  }

  //定義一個與函數TestFuction類型相同的函數指針lpproc

  TESTDLL lpproc;

  //搜尋**.dll中函數名為TestFuction的對外接口

  lpproc = (TESTDLL)GetProcAddress (hmod,"TestFuction");

  //如果搜尋成功

  if(NULL != lpproc)

  {

     int nType = 0;

     char* strPath = "Data";

     std::vector<string> vecData;

     //通過函數指針lpproc調用**.dll的接口函數TestFuction

     int nResult = (*lpproc)(nType,strPath,vecData);

  }

  //...

  //在恰當的時候釋放動态連結庫**.dll

  FreeLibrary(hmod);

}

方式二:采用子產品定義(.def)檔案聲明

首先建立 一個DLL程式(DllTestDef)

在*.cpp中

int __stdcall Add(int numa, int numb)

{

     return (numa + numb);

}

int __stdcall Sub(int numa, int numb)

{

     return (numa - numb);

}

然後建立一個.def的檔案,在裡面加上

;DllTestDef.lib : 導出DLL函數

;作者:----

LIBRARY DllTestDef

EXPORTS

Add @ 1

Sub @ 2

最後建立一個測試程式:.cpp檔案如下:

#include <iostream>

#include <windows.h>

using namespace std;

typedef int (__stdcall *FUN)(int, int);

HINSTANCE hInstance;

FUN   fun;

int main()

{

       hInstance = LoadLibrary("DLLTestDef.dll");

       if(!hInstance)

           cout << "Not Find this Dll" << endl;

       fun = (FUN)GetProcAddress(hInstance, MAKEINTRESOURCE(1));

       if (!fun)

       {

              cout << "not find this fun" << endl;

       }

       cout << fun(1, 2) << endl;

       FreeLibrary(hInstance);

       return 0;

}

說明:

.def檔案的規則為:

(1)LIBRARY語句說明.def檔案相應的DLL;

(2)EXPORTS語句後列出要導出函數的名稱。可以在.def檔案中的導出函數名後加@n,表示要導出函數的序号為n(在進行函數調用時,這個序号将發揮其作用);

(3).def 檔案中的注釋由每個注釋行開始處的分号 (;) 指定,且注釋不能與語句共享一行。

(4)使用__declspec(dllexport)和使用.def檔案是有差別的。

如果你的DLL是提供給VC使用者使用的,你隻需要把編譯DLL時産生的.lib提供給使用者,

它可以很輕松地調用你的DLL。但是如果你的DLL是供VB、PB、Delphi使用者使用的,那麼會産生一個小麻煩。

因為VC++編譯器對于__declspec(dllexport)聲明的函數會進行名稱轉換,如下面的函數:

__declspec(dllexport) int __stdcall Add()

會轉換為​​Add@0​​,這樣你在VB中必須這樣聲明: