WindowsでのDLLのエクスポート/インポートおよび外部に関する質問
-
10-07-2019 - |
質問
皆さん、Windows dllについて簡単な質問があります。
基本的に、ifdefを使用してdllexportとdllimportを処理していますが、実際の質問はdllexportsとdllimportsの配置とexternキーワードに関するものです。
dllimports / dllexportsをヘッダーファイルに配置していますが、dllexportとdllimportsを実際の定義に配置する必要がありますか?
typedefについてはどうですか?
dllimport / dllexportを前に配置しますか?
のようにdllexport typedef map<string, int> st_map
externキーワードについても、次のように使用されているのを見ました:
extern "C" {
dllexport void func1();
}
次のように使用されていることも確認しました:
extern dllexport func1();
&quot; C&quot;もう一方はそうではありません、私の質問は違いは何ですか、それを使用する必要がありますか?その場合、dllexportとdllimportの両方に使用しますか?ヘッダーファイルの宣言と定義の両方で使用する必要がありますか?
私のプロジェクトは共有ライブラリになります。エクスポートしたいいくつかのクラスファイル、エクスポートしたいtypdef、およびすべてをDLLにエクスポートしたいグローバル関数が含まれています。
誰もが私を教えてください?
編集:
さて、私がやったことの小さな抜粋を投稿すると思いました。また、LinuxとWindowsの両方のライブラリを構築しているので、それを確認します:
mydll.h
#ifdef WINDOWS
# ifdef PSTRUCT_EXPORT
# define WINLIB __declspec(dllexport)
# else
# define WINLIB __declspec(dllimport)
# endif
#else
# define WINLIB
#endif
WINLIB void funct1();
ソースコードの内容:
mydll.cpp
#define PSTRUCT_EXPORT
void funct1() <---- do i need to add WINLIB in front of it?
Or is doing it in the header enough?
解決
最初に、typedefをインポートまたはエクスポートする必要はありません。両方が使用するヘッダーファイルに含まれている限り、問題ありません。関数とクラス定義をインポート/エクスポートする必要があります。
おそらく、コードのインポートとエクスポートの両方に同じヘッダーファイルを使用するので、メイクファイルマジックを実行して各サイドでプリプロセッサマクロを定義し、次のように実行できます。
#if defined( LIBRARY_CODE )
#define MYAPI __declspec(dllexport)
#else
#define MYAPI __declspec(dllimport)
#endif
extern MYAPI void func1();
class MYAPI MyClass {
...
};
CとC ++の関数については、次のことができます。
#if defined( __cplusplus__ ) // always defined by C++ compilers, never by C
#define _croutine "C"
#else
#define _croutine
#endif
extern _croutine void function_with_c_linkage();
C ++ソースファイル(この関数の実装を含む)からこのヘッダーファイルをインポートするようにしてください。そうしないと、コンパイラはCリンケージを提供することを知りません。
他のヒント
- typedefsはdllimport / dllexportを必要とせず、単なる定義です
- dllimport / dllexportは標準ではありません。他のプラットフォーム/コンパイラ用にマクロを定義することを考えてください
- また、使用される呼び出し規約(cdecl、stdcall、...)を処理します。そうしないと、問題が発生します(Visual Basicでstdcallを使用する必要がある場合)
- extern&quot; C&quot;で囲むlibをC ++プログラム内から使用できるようにするには、#ifdef __cplusplusを使用して、C ++のみに表示されるようにします。
さまざまなOpenSourceライブラリをご覧ください。優れたライブラリヘッダーを作成する方法の例がたくさんあります。 extern&quot; C&quot;のないC ++の場合、名前の装飾に問題がある可能性があります。