2011-07-27 43 views
12

我有有兩個重載函數的類。我如何從dll中導出它,以及如何由其他C++類使用它?我的階級是這樣的:如何從dll導出C++類?

#define DECLDIREXP __declspec(dllexport) 

#define DECLDIRIMP __declspec(dllimport) 


class DECLDIREXP xyz 

{ 

public: 
      void printing(); 
      void printing(int a); 
}; 

using namespace std; 

void xyz::printing() 
{ 
     cout<<"hello i donot take any argument"; 
} 


void xyz::printing(int a) 
{ 
     cout<<"hello i take "<< a <<"as argument"; 
} 
+0

令我驚訝的是,我沒有找到這個重複的現有問題。我會認爲這是一個相當普遍的問題。 –

+0

檢查:http://stackoverflow.com/questions/6620791/exporting-classes-to-dlls – Ajay

回答

18

一種常見的方法是有一個宏(姑且稱之爲EXPORT),這兩種擴展到dllimportdllexport取決於某種「現在建設DLL」是否定義爲設置這樣的:

#ifdef MAKEDLL 
# define EXPORT __declspec(dllexport) 
#else 
# define EXPORT __declspec(dllimport) 
#endif 

class EXPORT xyz { 
    // ... 
}; 

的想法是,建立你的DLL時,您添加到MAKEDLL預處理器定義。這樣,所有的代碼將被導出。鏈接到您的DLL(因此包含此頭文件)的客戶端不需要執行任何操作。通過不定義MAKEDLL,它們將自動導入所有代碼。

這種方法的好處是,獲得宏的負擔權利從衆多(客戶機)移動到DLL的只是作者。

這樣做的缺點是,當使用上面的代碼時,不再可能將代碼直接編譯到某個客戶端模塊中,因爲無法將EXPORT宏定義爲無。要做到這一點,你需要再次檢查一下,如果真的,將EXPORT定義爲無。

在一個稍微不同的主題:在許多情況下,這是不可能導出一個完整的類這樣的(或期望的!)。相反,您可能只想導出您需要的符號。例如,就你而言,你可能想要導出兩個公共方法。這樣一來,所有的私有/ protected成員將不會導出:

class xyz 
{ 
public: 
    EXPORT void printing(); 
    EXPORT void printing(int a); 
}; 
+2

只記得Mehrdads答案是在出口類只爲這一特定版本的編譯器編譯器和設置工作方面是正確的。即使混合調試和發佈也是不允許的(例如使用發行版dll的調試客戶端)。 –

1

當編譯你的圖書館,你應該定義一個宏(命令行預處理器定義),我們稱之爲MY_DLL_EXPORT

然後在你的庫的代碼做這樣的事情:

#ifdef MY_DLL_EXPORT 
# define DLL_API __declspec(dllexport) 
#else 
# define DLL_API __declspec(dllimport) 
#endif 


class DLL_API some_class { /*...*/ } 
9

我記得,通常情況下,你不能導出一個類,但它創建類的一個新實例,並返回一個指向工廠函數。類聲明駐留在頭文件中供編譯時使用。

我可能是錯的例子(那是很久以前),但在這裏它應該如何大約是這樣的:

頭文件(.H):

class MyClass { ... }; 

extern "C" DLL_API MyClass* createMyClass(); 

的源文件(的.cpp ):

DLL_API MyClass* createMyClass() { 
    return new MyClass(); 
} 

定義MY_DLL_EXPORT在編譯時,看到foraidt的回答樣本。

+2

這是實現它的最簡單的方法。但不要忘記將工廠函數放在extern「C」{}語句中。 C++的名稱修改可能會阻止您從dll加載函數。 – holgac

+0

你可以給我一個示例 –

3

彼此選項:

使用默認定義的宏當地到項目中。

你可以看到默認定義的宏地方在以下位置的項目:

屬性 - > C/C++ - >預處理器 - >預處理器定義。

例子:

假設你的項目名稱爲:MYDLL

默認的宏局部的項目:MYDLL_EXPORTS

#ifdef MYDLL_EXPORTS 
    /*Enabled as "export" while compiling the dll project*/ 
    #define DLLEXPORT __declspec(dllexport) 
#else 
    /*Enabled as "import" in the Client side for using already created dll file*/ 
    #define DLLEXPORT __declspec(dllimport) 
#endif 


    class DLLEXPORT Class_Name { 
      //.... 
    }