Если вы хотите простой экспорт C, используйте проект C, а не C ++. DLL-библиотеки C ++ основаны на распределении имен для всех измов C ++ (пространства имен и т. Д.). Вы можете скомпилировать свой код как C, зайдя в настройки вашего проекта в C / C ++ -> Advanced, есть опция «Compile As», которая соответствует переключателям компилятора / TP и /TC.
Экспорт / Импорт библиотек DLL в VC ++
Что вы действительно хотите сделать, так это определить условный макрос в заголовке, который будет включен во все исходные файлы в вашем проекте 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, когда этот проект включает файл заголовка вашей библиотеки, все функции будут импортированы вместо него.
Если ваша библиотека должна быть кроссплатформенной, вы можете определить LIBRARY_API как ничего, если не в Windows:
#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. Два метода решают одну и ту же задачу по-разному, я считаю, что dllexport / dllimport является рекомендуемым методом из двух.
Экспорт неупорядоченных функций из C ++ DLL для LoadLibrary / PInvoke
Если вам нужно использовать LoadLibrary и GetProcAddress, или, возможно, сделать PInvoke из .NET, вы можете использовать extern "C"
inline со своим dllexport. И поскольку мы используем GetProcAddress вместо dllimport, нам не нужно выполнять танец 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")
);