DLL 匯出類的問題

2021-06-07 15:19:07 字數 2077 閱讀 1271

使用dll的乙個比較嚴重的問題就是編譯器之間的相容性問題。不同的編譯器對c++函式在二進位制級別的實現方式是不同的。所以對基於c++的dll,如果編譯器­不同就有很麻煩的。如果建立的是mfc擴充套件dll,就不會存在問題,因為它只能被動態連線到mfc的客戶應用程式。這裡不是本文討論的重點。

一、重新編譯問題

我們先來看乙個在實際中可能遇到的問題:

比如現在建立好了乙個dll匯出了cmyclass類,客戶也能正常使用這個dll,假設cmyclass物件的大小為30位元組。如果我們需要修改dll 中的cmyclass類,讓它有相同的函式和成員變數,但是給增加了乙個私有的成員變數int型別,現在cmyclass物件的大小就是34位元組了。當直接把這­個新的dll給客戶使用替換掉原來30位元組大小的dll,客戶應用程式期望的是30位元組大小的物件,而現在卻變成了乙個34位元組大小的物件,糟糕,客戶程式出錯­了。

類似的問題,如果不是匯出cmyclass類,而在匯出的函式中使用了cmyclass,改變物件的大小仍然會有問題的。這個時候修改這個問題的唯一辦法就是替­換客戶程式中的cmyclass的標頭檔案,全部重新編譯整個應用程式,讓客戶程式使用大小為34位元組的物件。

這就是乙個嚴重的問題,有的時候如果沒有客戶程式的源**,那麼我們就不能使用這個新的dll了。

二、解決方法

為了能避免重新編譯客戶程式,這裡介紹兩個方法:(1)使用介面類。(2)使用建立和銷毀類的靜態函式。

1、使用介面類

使用介面類也就是建立第二個類,它作為要匯出類的介面,所以在匯出類改變時,也不需要重新編譯客戶程式,因為介面類沒有發生變化。

假設匯出的cmyclass類有兩個函式functiona和functionb。現在建立乙個介面類cmyinte***ce,下面就是在dll中的cmyinte***ce類的標頭檔案的**:

#include "myclass.h" 

class _declspec(dllexport) cmyinte***ce   

;  

而在客戶程式中的標頭檔案稍不同,不需要include語句,因為客戶程式沒有它的拷貝。相反,使用乙個cmyclass的向前宣告,即使沒有標頭檔案也能編譯:

class _declspec(dllexport) cmyinte***ce  

;  

在dll中的cmyinte***ce的實現如下:

cmyinte***ce::cmyinte***ce()  

cmyinte***ce::~cmyinte***ce()  

int cmyinte***ce::functiona()  

int cmyinte***ce::functionb()  

//.....

對匯出類cmyclass的每個成員函式,cmyinte***ce類都提供自己的對應的函式。客戶程式與cmyclass沒有聯絡,這樣任意改cmyclass也不會有問題,因為cmyinte***ce類的大小沒有發生變化。即使為了能訪問cmyclass中的新增變數而給cmyinte***ce類加了函式也不會有問題的。

但是這種方法也存在明顯的問題,對匯出類的每個函式和成員變數都要對應實現,有的時候這個介面類會很龐大。同時增加了客戶程式呼叫所需要的時間。增加了程式的開銷。

2、使用靜態函式

還可以使用靜態函式來建立和銷毀類物件。建立乙個匯出類的時候,增加兩個靜態的公有函式createme()/destroyme(),標頭檔案如下:

class _declspec(dllexport) cmyclass  

;  

實現函式就是:

cmyclass * cmyclass::cmyclass()  

void cmyclass::destroyme(cmyclass *ptr)    

然後象其他類一樣匯出cmyclass類,這個時候在客戶程式中使用這個類的方法稍有不同了。如若想建立乙個cmyclass物件,就應該是:

cmyclass x;  

cmyclass *ptr = cmyclass::createme();  

在使用完後刪除:

cmyclass::destroyme(ptr); 

dll匯出類的實現

首先是在dll中實現類得宣告 新增inc.h標頭檔案 cpp view plain copy class declspec dllexport cpreson 在dllmain.cpp中或自定義個個inc.cpp檔案實現類 cpp view plain copy cpreson cpreson cp...

C 的dll匯出類

首先建乙個dll 專案 然後做乙個公用的標頭檔案 export.h ifndef export h define export h struct icalculator endif 這個標頭檔案封轉乙個基類 然後再dll模組中做乙個子類,繼承於這個基類 calculator.h ifndef cal...

DLL中匯出類

dll中定義的類可以在應用工程中使用。下面的例子裡,我們在dll中定義了point和circle兩個類,並在應用工程中引用了它們。檔名 point.h,point類的宣告 ifndef point h define point h ifdef dll file class declspec dlle...