Действительно, мы были создателями библиотеки, и после долгой битвы мы смогли разобраться в проблеме. В случае, если это полезно для кого-то еще, здесь идет ответ.
Библиотека создавалась с использованием CMake, и чтобы избежать необходимости экспортировать символы вручную (используя __declspec(export)
, мы просто включили
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS on)
Однако выполнение этого в DLL подразумевает, что Visual Studio экспортирует не только символы, определенные в самой DLL, но и в ее унаследованных зависимостях (как, например, весь STL).
Предыдущее (я не совсем уверен, почему) не проблема, вы связываете эту библиотеку как часть сборки исполняемого файла (так как у нас есть C ++ EXE, который успешно использует эту DLL), но это Основная проблема, если вы связываете DLL с другой DLL (как в случае с CLI / C ++, где вы в основном создаете одну DLL, чтобы обернуть другую DLL). В последнем случае CLI DLL также попытается импортировать символы из системы, что приведет к ранее отображенному переопределению:
error LNK2005: "public: virtual char const * __cdecl std::exception::what(void)const " (?what@exception@std@@UEBAPEBDXZ) already defined in ... fatal error LNK1169: one or more multiply defined symbols found
Один из способов проверить это - посмотреть файл экспорта (.def), сгенерированный базовой C ++ DLL (не CLI), он содержит std::exception::what
(среди многих других), хотя эта DLL никогда не определялась это само по себе.
Итак, решение было довольно простым:
- Отключить
CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
.
- Экспорт / импорт явно нужных символов из DLL (используя
__declspec(export|import)
.