DLL入門系列四

來源:互聯網
上載者:User

為了便於學習,本系列文章轉載於http://www.cppblog.com/suiaiguo/archive/2009/07/20/90619.html,如果需要轉載,請註明轉載原網址。

前面介紹了怎麼從DLL中匯出函數和變數,實際上匯出類的方法也是大同小異,廢話就不多說了,下面給個簡單例子示範一下,也就不多做解釋了。

DLL標頭檔:

#ifndef _DLL_SAMPLE_H
#define _DLL_SAMPLE_H

// 通過宏來控制是匯入還是匯出
#ifdef _DLL_SAMPLE
#define DLL_SAMPLE_API __declspec(dllexport)
#else
#define DLL_SAMPLE_API __declspec(dllimport)
#endif

// 匯出/匯入變數聲明
DLL_SAMPLE_API class DLLClass
{
  public:
    void Show();
};

#undef DLL_SAMPLE_API

#endif

DLL實現檔案:

#include "stdafx.h"
#define _DLL_SAMPLE

#ifndef _DLL_SAMPLE_H
#include "DLLSample.h"
#endif

#include "stdio.h"

//APIENTRY聲明DLL函數進入點
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
 switch (ul_reason_for_call)
 {
  case DLL_PROCESS_ATTACH:
  case DLL_THREAD_ATTACH:
  case DLL_THREAD_DETACH:
  case DLL_PROCESS_DETACH:
   break;
 }
 return TRUE;
}

void DLLClass::Show()
{
  printf("DLLClass show!");
}

應用程式調用DLL

#include "DLLSample.h"

#pragma comment(lib,"DLLSample.lib")


int main(int argc, char *argv[])
{
 DLLClass dc;
  dc.Show();
 return 0;
}

大家可能發現了,上面我沒有使用模組定義檔案(.def)聲明匯出類也沒有用顯式連結匯入DLL。
用Depends查看前面編譯出來的DLL檔案,會發現裡面匯出了很奇怪的symbol,這是因為C++編譯器在編譯時間會對symbol進行修飾。
這是我從別人那兒轉來的。

網上找了下,發現了C++編譯時間函數名的修飾約定規則

__stdcall呼叫慣例:

1、以"?"標識函數名的開始,後跟函數名;
2、函數名後面以"@@YG"標識參數表的開始,後跟參數表;
3、參數表以代號表示:

X——void,
D——char,
E——unsigned char,
F——short,
H——int,
I——unsigned int,
J——long,
K——unsigned long,
M——float,
N——double,
_N——bool,
....

  PA——表示指標,後面的代號表明指標類型,如果相同類型的指標連續出現,以"0"代替,一個"0"代表一次重複;
4、參數表的第一項為該函數的傳回值類型,其後依次為參數的資料類型,指標標識在其所指資料類型前;
5、參數表後以"@Z"標識整個名字的結束,如果該函數無參數,則以"Z"標識結束。
  其格式為"?functionname@@YG*****@Z"或?functionname@@YG*XZ,

    int Test1(char *var1,unsigned long)-----“?Test1@@YGHPADK@Z”     void Test2()                          -----“?Test2@@YGXXZ”

__cdecl呼叫慣例:
  規則同上面的_stdcall呼叫慣例,只是參數表的開始標識由上面的"@@YG"變為"@@YA"。

__fastcall呼叫慣例:
  規則同上面的_stdcall呼叫慣例,只是參數表的開始標識由上面的"@@YG"變為"@@YI"。

VC++對函數的省缺聲明是"__cedcl",將只能被C/C++調用。

雖然因為C++編譯器對symbol進行修飾的原因不能直接用def檔案聲明匯出類和顯式連結,但是可以用另外一種取巧的方式。

在標頭檔中類的聲明中添加一個友元函數:
friend DLLClass* CreatDLLClass();
然後聲明CreatDLLClass()為匯出函數,通過調用該函數返回一個DLLClass類的對象,同樣達到了匯出類的目的。
這樣,就可以用顯式連結來調用CreatDLLClass(),從而得到類對象了。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.