プレーンCエクスポートが必要な場合は、C ++ではなくCプロジェクトを使用してください。C ++ DLLは、すべてのC ++ ism(名前空間など)の名前変換に依存しています。C / C ++-> Advancedのプロジェクト設定に移動することで、コードをCとしてコンパイルできます。コンパイラスイッチ/ TPおよび/ TCに対応する「Compile As」オプションがあります。
C ++を使用してlibの内部を記述したいが、C ++の外部で使用するためにいくつかの関数を展開せずにエクスポートする場合は、以下の2番目のセクションを参照してください。
VC ++でのDLLライブラリのエクスポート/インポート
あなたが本当にやりたいことは、DLLプロジェクトのすべてのソースファイルに含まれるヘッダーに条件付きマクロを定義することです。
#ifdef LIBRARY_EXPORTS
# define LIBRARY_API __declspec(dllexport)
#else
# define LIBRARY_API __declspec(dllimport)
#endif
次に、エクスポートしたい関数で使用しますLIBRARY_API
:
LIBRARY_API int GetCoolInteger();
ライブラリビルドプロジェクトで定義を作成します。LIBRARY_EXPORTS
これにより、関数がDLLビルド用にエクスポートされます。
LIBRARY_EXPORTS
DLLを使用するプロジェクトでは定義されないため、そのプロジェクトにライブラリのヘッダーファイルが含まれている場合は、代わりにすべての関数がインポートされます。
ライブラリがクロスプラットフォームになる場合、Windows以外ではLIBRARY_APIを何も定義しないことができます。
#ifdef _WIN32
# ifdef LIBRARY_EXPORTS
# define LIBRARY_API __declspec(dllexport)
# else
# define LIBRARY_API __declspec(dllimport)
# endif
#elif
# define LIBRARY_API
#endif
dllexport / dllimportを使用する場合、DEFファイルを使用する必要はありません。DEFファイルを使用する場合、dllexport / dllimportを使用する必要はありません。2つのメソッドは同じタスクをさまざまな方法で実行します。dllexport/ dllimportが2つのうちの推奨されるメソッドであると思います。
LoadLibrary / PInvokeのC ++ DLLからマングルされていない関数をエクスポートする
LoadLibraryとGetProcAddressを使用するためにこれが必要な場合、または別の言語(つまり、.NETからのPInvoke、またはPython / RのFFIなど)からインポートする場合extern "C"
は、dllexportでインラインを使用して、C ++コンパイラに名前を壊さないように指示できます。また、dllimportの代わりにGetProcAddressを使用しているため、上からifdefダンスを実行する必要はなく、単純なdllexportを使用します。
コード:
#define EXTERN_DLL_EXPORT extern "C" __declspec(dllexport)
EXTERN_DLL_EXPORT int getEngineVersion() {
return 1;
}
EXTERN_DLL_EXPORT void registerPlugin(Kernel &K) {
K.getGraphicsServer().addGraphicsDriver(
auto_ptr<GraphicsServer::GraphicsDriver>(new OpenGLGraphicsDriver())
);
}
Dumpbin / exportsでのエクスポートの様子は次のとおりです。
Dump of file opengl_plugin.dll
File Type: DLL
Section contains the following exports for opengl_plugin.dll
00000000 characteristics
49866068 time date stamp Sun Feb 01 19:54:32 2009
0.00 version
1 ordinal base
2 number of functions
2 number of names
ordinal hint RVA name
1 0 0001110E getEngineVersion = @ILT+265(_getEngineVersion)
2 1 00011028 registerPlugin = @ILT+35(_registerPlugin)
したがって、このコードは正常に機能します。
m_hDLL = ::LoadLibrary(T"opengl_plugin.dll");
m_pfnGetEngineVersion = reinterpret_cast<fnGetEngineVersion *>(
::GetProcAddress(m_hDLL, "getEngineVersion")
);
m_pfnRegisterPlugin = reinterpret_cast<fnRegisterPlugin *>(
::GetProcAddress(m_hDLL, "registerPlugin")
);
extern C
関数のパラメーター型を表す装飾を削除しますが、関数の呼び出し規約を表す装飾は削除しません。b)すべての装飾を削除するには、DEFファイルで(装飾されていない)名前を指定する必要があります。