Я разработал внутрипроцессорный COM-сервер на основе C ++ DLL и успешно скомпилировал его с MinGW + MSYS.Если я скомпилирую его с --enable-stdcall-fixup -Wl,DLLMain.def
, то все, что связано с COM-сервером, работает как шармОднако таким образом некоторые символы экспортируются дважды:
'dlltool -z output.def --export-all-символы libCOMTest.dll' создает:
EXPORTS
...
DeleteCriticalSection@4 @ 14
DllCanUnloadNow @ 15 DATA
DllCanUnloadNow@0 @ 16
DllGetClassObject @ 17 DATA
DllGetClassObject@12 @ 18
DllMain @ 19 DATA
DllMainCRTStartup@12 @ 20
DllRegisterServer @ 21 DATA
DllRegisterServer@0 @ 22
DllUnregisterServer @ 23 DATA
DllUnregisterServer@0 @ 24
EnterCriticalSection@4 @ 25
...
И компоновщикгенерирует несколько предупреждений:
Warning: resolving _DllMain by linking to _DllMain@12
Use --enable-stdcall-fixup to disable these warnings
Use --disable-stdcall-fixup to disable these fixups
Warning: resolving _DllGetClassObject by linking to _DllGetClassObject@12
Warning: resolving _DllCanUnloadNow by linking to _DllCanUnloadNow@0
Warning: resolving _DllRegisterServer by linking to _DllRegisterServer@0
Warning: resolving _DllUnregisterServer by linking to _DllUnregisterServer@0
Если я опускаю эти параметры компилятора, подпрограмма DllMain
не экспортируется, поэтому я даже не могу зарегистрировать свой COM-сервер с помощью утилиты regsvr32
.
Ниже приведены некоторые из экспортируемых символов libCOMTest.dll:
EXPORTS
...
DeleteCriticalSection@4 @ 14
DllCanUnloadNow@0 @ 15
DllGetClassObject@12 @ 16
DllMainCRTStartup@12 @ 17
DllRegisterServer@0 @ 18
DllUnregisterServer@0 @ 19
EnterCriticalSection@4 @ 20
...
Как вы можете видеть, в списке нет подпрограммы DllMain
.
Мой файл .def выглядит следующим образом:
LIBRARY libCOMTest
DESCRIPTION 'libCOMTest in-proc server'
EXPORTS
DllMain @1 PRIVATE
DllGetClassObject @2 PRIVATE
DllCanUnloadNow @3 PRIVATE
DllRegisterServer @4 PRIVATE
DllUnregisterServer @5 PRIVATE
По какой причине процедура DllMain
была экспортирована без --enable-stdcall-fixup
переключателя компиляции?Существуют ли какие-либо специальные приемы для построения внутрипроцессного COM-сервера с MinGW + MSYS?
Решение # 1
Как предложил Ганс в своем ответе, можно использовать синтаксис переименования вфайл .def выглядит следующим образом:
EXPORTS
DllGetClassObject = DllGetClassObject@12
DllCanUnloadNow = DllCanUnloadNow@0
DllRegisterServer = DllRegisterServer@0
DllUnregisterServer = DllUnregisterServer@0
В руководстве по созданию и использованию DLL-библиотек Win32 в Haskell предлагается то же самое.
Решение # 2
Другой способ - использовать переключатель компоновщика --kill-at
для удаления части @nn:
--kill-at
If given, the stdcall suffixes (@nn) will be stripped from symbols
before they are exported.