web-dev-qa-db-ja.com

DLLからC ++クラスをエクスポートする方法

2つのオーバーロードされた関数を持つクラスがあります。 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";
}
20
Apoorva sahay

一般的なアプローチは、次のように、ある種の「DLLを今すぐ構築する」定義が設定されているかどうかに応じて、EXPORTまたはdllimportに展開される単一のマクロ(dllexportと呼びます)を持つことです。

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

class EXPORT xyz {
  // ...
};

DLLをビルドするときに、プリプロセッサ定義にMAKEDLLを追加するという考え方です。これにより、すべてのコードがエクスポートされます。 DLLにリンクしている(したがって、このヘッダーファイルをインクルードしている)クライアントは、何もする必要はありません。 MAKEDLLを定義しないと、すべてのコードが自動的にインポートされます。

このアプローチの利点は、マクロを正しく取得する負担が多数(クライアント)からDLLの作成者だけに移されることです。

これの欠点は、上記のコードをそのまま使用すると、EXPORTマクロを何も定義できないため、コードを一部のクライアントモジュールに直接コンパイルすることができなくなることです。これを実現するには、真の場合にEXPORTを何にも定義しない別のチェックが必要になります。

少し異なるトピックについて:多くの場合、そのような完全なクラスをエクスポートすることは不可能です(または望まれません!)。代わりに、必要なシンボルだけをエクスポートすることもできます。たとえば、あなたのケースでは、2つのパブリックメソッドをエクスポートしたい場合があります。そうすれば、すべてのプライベート/保護されたメンバーはエクスポートされません:

class xyz
{
public: 
    EXPORT void printing();
    EXPORT void printing(int a);
};
30
Frerich Raabe

私が覚えているように、通常、クラスではなく、クラスの新しいインスタンスを作成してポインターを返すファクトリー関数をエクスポートします。クラス宣言は、コンパイル時にヘッダーファイルに存在します。

私はこの例(それはずっと前に)について間違っているかもしれませんが、ここではそれがおおよそのように見えるはずです:

ヘッダーファイル(.h):

class MyClass { ... };

extern "C" DLL_API MyClass* createMyClass();

ソースファイル(.cpp):

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

コンパイル中にMY_DLL_EXPORTを定義します。Foraidtの回答例を参照してください。

9
weekens

もう1つのオプション:

プロジェクトにdefault定義済みマクロlocalを使用します。

以下の場所で、プロジェクトにローカルに定義されたデフォルトのマクロを確認できます。

プロパティ-> 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 { 
             //.... 
  }
3
SridharKritha

ライブラリをコンパイルするときは、マクロ(コマンドラインプリプロセッサ定義)を定義する必要があります。それをMY_DLL_EXPORT

次に、ライブラリのコードで次のようにします。

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


class DLL_API some_class { /*...*/ }
1
foraidt