Ошибка компоновки в проекте C ++ / CLI при переносе общей библиотеки C ++ - PullRequest
0 голосов
/ 12 сентября 2018

Я пытаюсь обернуть библиотеку C ++, чтобы ее могли использовать управляемые проекты. Используемая мной сторонняя библиотека является общей библиотекой. Он предназначен для ссылки на время загрузки. У меня есть заголовочные файлы, файл .lib, который является библиотекой импорта DLL, и файл .DLL.

Это то, что я сделал до сих пор: - 1. Создан проект CLR. 2. Добавлен путь к заголовочному файлу в C / C ++ -> General-> Additional Включить каталоги 3. Установите «Дополнительные каталоги библиотек» в Linker-> General. 4. Добавлено имя библиотеки в Linker-> Input-> Additional Dependencies

После этого я получаю сообщение об ошибке LNK2005, за которым следует LNK1169. Единственное, что я сделал после создания проекта, это включил заголовочный файл из библиотеки C ++, который я пытаюсь обернуть. Что я делаю не так?

ошибка LNK2005: "public: virtual char const * __cdecl std :: exception :: what (void) const" (? What @ exception @ std @@ UEBAPEBDXZ) уже определено в ... фатальная ошибка LNK1169: найден один или несколько кратно определенных символов

Ответы [ 2 ]

0 голосов
/ 22 ноября 2018

Действительно, мы были создателями библиотеки, и после долгой битвы мы смогли разобраться в проблеме. В случае, если это полезно для кого-то еще, здесь идет ответ.

Библиотека создавалась с использованием 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 никогда не определялась это само по себе.

Итак, решение было довольно простым:

  1. Отключить CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.
  2. Экспорт / импорт явно нужных символов из DLL (используя __declspec(export|import).
0 голосов
/ 15 сентября 2018

Возможно, вы пытаетесь статически связать две разные версии стандартной библиотеки.Проверяли ли вы со сторонним поставщиком библиотеки, чтобы определить, какую версию Visual Studio / C ++ они использовали для создания этой библиотеки?

Кроме того, при устранении неполадок с сторонними библиотеками следует попытаться связать простую ссылкуИсполняемый файл командной строки, прежде чем пытаться создать библиотеку C ++ / CLI.

И да, если возможно, вы должны статически связать нативную библиотеку C ++ с вашей DLL C ++ / CLI.Это облегчит развертывание.Предположительно, это будет единственная сборка C ++ / CLI, которую будет использовать ваше приложение C #.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...