web-dev-qa-db-ja.com

DLLを使用してクラスをエクスポートする場合の__declspec(dllimport)の未解決の外部シンボル

Dllエクスポートクラスに基づいて派生クラスを定義したいのですが。基本クラスはプロジェクトAで定義され、派生クラスはプロジェクトBにあります。

まず、プロジェクトAでは、プリプロセッサMYDLL_BUILDが定義されています。そして、ヘッダーファイルを使用してエクスポート/インポートを指定します。

    #if !defined(MYDLL_BUILD)
    #   pragma comment(lib, "myDll.lib")
    #endif

    #if defined(MYDLL_BUILD)
    #   define MYDLL_API __declspec(dllexport)
    #else
    #   define MYDLL_API __declspec(dllimport)
    #endif

次に、基本クラスを定義します。

class MYDLL_API DllObject
{
public:
    virtual ~DllObject() {}
protected:
    DllObject() { m_count = 3; }
private:
    int m_count;
};

プロジェクトBでは、プリプロセッサMYDLL_BUILDが定義されていません。派生クラスは次のとおりです。

class MyClass : public DllObject
{
public:
    ~MyClass(){}
    MyClass() { m_data = 20; }
private:
    int m_data;
}; 

Dllファイルとlibファイルを含めましたが、未解決の外部シンボルエラーが発生します。

2>Test_Entry.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual __thiscall ADAI::DllObject::~DllObject(void)" (__imp_??1DllObject@ADAI@@UAE@XZ) referenced in function "public: virtual __thiscall MyClass::~MyClass(void)" (??1MyClass@@UAE@XZ)
2>Test_Entry.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) protected: __thiscall ADAI::DllObject::DllObject(void)" (__imp_??0DllObject@ADAI@@IAE@XZ) referenced in function "public: __thiscall MyClass::MyClass(void)" (??0MyClass@@QAE@XZ)
2>c:\Users\Adai\Documents\Visual Studio 2010\Projects\Test_Main\Debug\Test_Main.exe : fatal error LNK1120: 2 unresolved externals

私はオンラインで検索しましたが、ほとんどの回答はlibが欠落していると主張しています。しかし、それらの指示は私の問題を解決しません。

私が変わるとき

    class MYDLL_API DllObject

    class __declspec(dllexport) DllObject 

ソリューションはエラーなしでコンパイルされます。その理由がよくわかりません。誰か助けてくれますか?前もって感謝します。

17
Chtoucas

理由はインライン化です。

つまり、C++では、インライン関数を可能にするために、エラーを発生させることなく、同じ関数定義を複数のコンパイル単位(基本的には.cppファイル)に含めてコンパイルできるようにする必要があります。コンパイラは、この定義のコードを出力できますが、出力する必要はありません。次に、リンカーは1つのコピーを選択できます。

コピーを1つだけエクスポートする必要があるため、dllの作成が複雑になりますが、コンパイラは正しいコピーがどれであるかわかりません。この場合、DllObject.cppにいくつかのコードを追加することで、コンパイラーがDllObjectのコードを発行し、リンカーがエクスポートするDllObject::~DllObjectのコピーをいくつか持っていました。

私はあなたのプロジェクトの完全なソースとコンパイルのオプションを知らないので、あなたの特定のケースの詳細な説明を与えることはできません。

6