web-dev-qa-db-ja.com

DLLからグローバル変数をエクスポートする

DLLからグローバル変数をエクスポートしようとしています。

Foo.h

class Foo
{
public:
    Foo()
    {}
};

#ifdef PROJECT_EXPORTS
    #define API __declspec(dllexport)
#else
    #define API __declspec(dllimport)
#endif

API const Foo foo;

Foo.cpp

#include "Foo.h"

const Foo foo;

上記のコードをコンパイルすると、VisualStudioは次のように文句を言います。

foo.cpp(3):エラーC2370: 'foo':再定義;異なるストレージクラス1> foo.h(14):「foo」の宣言を参照

私が使用する場合:

external const Foo foo;

foo.hでは、コンパイラは問題ありませんが、DLLはシンボルをエクスポートしません。問題のある関数をエクスポートできましたが、変数は同じように機能しないようです。 。 何か案は?

21
Gili

ヘッダー内:

API extern const Foo foo;

ソースファイル内:

API const Foo foo;

externキーワードがない場合、Cコンパイラはローカル変数を宣言するつもりであると想定します。 (ヘッダーファイルからの定義がたまたまインクルードされていてもかまいません。)また、ソースファイルで実際に宣言するときに、変数のエクスポートを計画していることをコンパイラーに通知する必要があります。

29

クラスFooは、実際にはメンバー関数を持っている可能性が高く、別のモジュールからそれらを呼び出すと、OP /受け入れられた回答でリンカーエラーが発生します。このモジュールの外部でクラスのエクスポートされたインスタンスを使用してリンクエラーを排除するには、クラスをdll export/importとしても定義する必要があります。

class API Foo
{
public:
    Foo()
    {}
    void DoSomeWork(); // calling this would cause link error if Foo is not defined as import/export class
};

そうは言っても、#define AP​​Iの名前をDLLEXPORTのような名前に変更して、APIとエクスポートクラスの両方に意味があるようにする方がよい場合があります。

1
zar