2015-10-08 3 views
0

У меня есть сборка в .NET, которую я выставил через COM и сильно назван.Необработанное исключение при попытке загрузить COM-обернутую DLL в C++

После развертывания эта сборка должна присутствовать в GAC. Тем не менее, мне нужно проверить, существует ли он до создания его объекта.

К сожалению, даже при создании объекта в результате попытки/улавливания получается unhandled exception во время выполнения, если сборка отсутствует в GAC.

Так что для меня должен быть какой-то способ проверить, действительно ли DLL установлена ​​в GAC, прежде чем я начну создавать объект.

HINSTANCE histLib; 
    histLib = LoadLibrary("CLSInterOpLibrary.dll"); 
    if (histLib == NULL) 
     return false; 
    encode(); 

    CoInitialize(NULL); 
    try 
    { 
     CLSInterOpLibrary::CLSInterOpInterfacePtr p(__uuidof(CLSInterOpLibrary::CLSInterOpClass)); 
     if (p == nullptr) 
      return false; 
     com_ptr = p; 
    } 
    catch (exception &e) 
    { 

    } 

LoadLibrary дает NULL, независимо от того, присутствуют ли в GAC или нет в библиотеке, вероятно, нуждается в каком-то пути ... и

CLSInterOpLibrary::CLSInterOpInterfacePtr p(__uuidof(CLSInterOpLibrary::CLSInterOpClass)); 

..gives необработанного исключения, если DLL нет.

Как можно проверить, установлен ли DLL в GAC с C++? Или есть более элегантное решение?

+1

http://stackoverflow.com/questions/14031749/where-is-loadlibrary-a-looking-for-the-file –

+0

Даже если я выберу библиотеку и поместил ее в каталог проекта, «LoadLibrary» преуспеет , но создание COM-объекта происходит с ошибкой, так как «CLASS NOT REGISTERED» и генерирует необработанное исключение. – user1173240

+1

http://www.codeproject.com/Articles/12673/Calling-Managed-NET-C-COM-Objects-from-Unmanaged-C –

ответ

1

Do не вызов LoadLibrary(), вероятность того, что это будет работать, очень мала, особенно если сборка фактически установлена ​​в GAC. Поиск DLL - это работа COM, он использует ключи реестра, которые были записаны при регистрации сборки.

Необходимо исправить вашу обработку ошибок, тип интеллектуального указателя CLSInterOpInterfacePtr, полученный из директивы #import, превращает коды ошибок HRESULT в исключения. Вам нужно попробовать/поймать, чтобы поймать _com_error exception. Попытка поймать std :: exception не будет работать, _com_error не вытекает из нее.

Что хорошего достаточно, чтобы также диагностику проблемы с регистрацией или сбойной библиотеки DLL. Шаблон _com_error :: Значение ошибки, которое вы получаете, это REGDB_E_CLASSNOTREG (0x80040154), «Класс не зарегистрирован», если COM-сервер не был зарегистрирован, что-то более конкретное, если CLR не удается найти DLL. Метод _com_error :: Description() предоставляет вам несколько разумное сообщение, которое вы можете отображать или регистрировать. Священная стоп-трасса недоступна.

+0

Спасибо. Я постараюсь сделать то, что вы предлагаете. Чтение в него пролило свет, который исключает исключения std :: exception и _com. То, что я сделал на данный момент, - это попытаться создать объект с использованием CoCreateInstance, и если я не смогу его создать, то полностью отказаться от него. Надеюсь, этот подход верен. – user1173240

+0

Это не улучшение по сравнению с тем, что у вас уже есть. Использование умного указателя CLSInterOpInterfacePtr в порядке, используйте его последовательно. Вы должны иметь дело с исключением _com_error не только для создания объекта, но и для вызовов методов. Исключения хороши, вы никогда не можете забыть протестировать HRESULT. –

+0

ОК. Я сделаю это так. еще раз спасибо – user1173240

Смежные вопросы