C ++, вызывающий управляемый COM-объект, не может найти зависимые сборки - PullRequest
1 голос
/ 03 февраля 2010

Я создал и зарегистрировал управляемую библиотеку COM в C # на моей машине для разработки. Я успешно зарегистрировал его, создал файл .tlb с помощью regasm и успешно импортировал tlb в консольное приложение c ++, используемое для тестирования.

Моя сборка COM называется "efcAPI.dll", и она ссылается на другую сборку, которая не была настроена для COM или не зарегистрирована в любом случае и называется "efcServerDiscovery.dll". Эта вторая DLL содержит некоторый код, используемый моей COM DLL и находится в той же папке, что и efcAPI.dll.

Все, что касается загрузки COM-сборки, работает нормально. Я могу создавать экземпляры своих классов, определенных в COM, и вызывать из них методы. Однако, когда я вызываю определенные методы, которые используют код, определенный в efcServerDiscovery.dll, я получаю _com_error, который сообщает, что не может загрузить файл или сборку 'efcServerDiscovery'.

Я проверил, что везде на моем жестком диске, где существует efcAPI.dll, есть копия efcServerDiscovery.dll (это просто папка, из которой я создал и зарегистрировал efcAPI.dll). Я также попытался поместить efcAPI.dll и efcServerDiscovery.dll в один каталог с приложением c ++, но безуспешно.

Любые предложения о том, где приложение c ++ ищет сборку или как узнать, где она ищет, было бы замечательно!

Ответы [ 4 ]

2 голосов
/ 03 февраля 2010

Да, это проблема с компонентами COM, имеющими не-COM-зависимости.Windows не учитывает местоположение COM DLL при поиске зависимых DLL.Действуют обычные правила поиска: папка, которая содержит в первую очередь EXE, каталоги Windows, текущий рабочий каталог, среда PATH.Расположение COM-сервера не играет роли.

При условии, что вы не хотите развертывать в папке EXE, ни одно из этих мест не является хорошим местом для хранения вашей DLL, хотя многие установщики сделали отчаянное движениесохранить его в c: \ windows \ system32 или изменить системную переменную среды PATH.

Одна вещь, которую вы можете сделать, это P / Invoke SetDllDirectory () в вашем коде C # перед запуском любого кода в DLL.Используя Assembly.GetExecutingAssembly (). Location сделает это.Однако это небезопасно, так как это может изменить правила поиска для приложения, использующего ваш компонент.

Единственное реальное решение - это установить DLL в параллельный кеш Windows (WinSxS) и включить манифест в ваш C # исполняемый файл.Учитывая состояние документации , я могу только пожелать вам удачи.

1 голос
/ 03 февраля 2010

В этих ситуациях я всегда начинаю с Dependency Walker , проверяющего, что и где он пытается загрузить это то, что я думаю.

0 голосов
/ 03 февраля 2010

Или используйте GAC.

(вот ваши персонажи, стека переполнения)

0 голосов
/ 03 февраля 2010

fuslogvw сообщит вам, где CLR ищет сборки

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