DllNotFoundException Из С#, но не из VB.NET

У меня есть сторонняя DLL для интеграции с их приложением. Это 32-битная C++ DLL, которая не раскрывает себя через COM, и мне не предоставили исходный код или заголовочный файл.

Он был снабжен рабочим кодом примера VB.NET в примере WinForms. Это работает до тех пор, пока исполняемый файл запускается из того же каталога, что и библиотека DLL API, и приложение, с которым взаимодействует API.

Я использовал пример объявления функции:

Declare Ansi Function GetVersion Lib "ThirdPartyAPI.dll" () As Integer

Однако мы будем использовать вызовы API из библиотеки C# для использования на веб-сайте или веб-службе, поэтому я преобразовал пример кода VB в

[DllImport("ThirdPartyAPI.dll", SetLastError = true, CharSet = CharSet.Ansi)]
public static extern int GetVersion();

Если я вызываю это из библиотеки С#, я получаю сообщение об ошибке

Unhandled Exception: System.DllNotFoundException: Unable to load DLL
'ThirdPartyAPI.dll': A dynamic link library (DLL) initialization
routine failed. (Exception from HRESULT: 0x8007045A)

Я выбрал альтернативный путь и поместил исходный рабочий код VB из примера в свою собственную библиотеку VB.NET и вызвал ее через C#. У меня такая же ошибка. Как ни странно, вызов VB.NET DLL из консольного приложения VB.NET работает.

В итоге:

  • Простое консольное приложение VB.NET будет работать
  • Простое приложение VB.NET WinForms будет работать
  • Простое консольное приложение VB.NET может вызывать GetVersion через DLL VB.NET.
  • Простое консольное приложение C# не может вызывать GetVersion через VB.NET DLL
  • Простое консольное приложение C# не может вызывать GetVersion напрямую. Это может быть связано с неправильным определением вызовов функций. На данном этапе я не слишком беспокоюсь об этом.
  • 32-битная компиляция не решает проблему
  • Я пробовал это на Server 2008 R2 и Windows 7 Enterprise.

Я создал хост WCF через службу NT, чтобы предоставить доступ к функциям, надеясь, что это будет работать с расположением файлов и зависимостями. Это было написано на VB.NET и помещено в ту же папку, что и ThirdPartyApi.dll.

  • Ни один из кодов службы NT не смог получить доступ к GetVersion.
  • Ни один из кодов службы WCF не может получить доступ к GetVersion.

Обратите внимание, что во всех вышеперечисленных случаях исполняемые файлы находятся в том же каталоге, что и ThirdPartyApi.dll. Все его зависимости также существуют в этом каталоге.

Может ли кто-нибудь объяснить это поведение или предложить, как это можно заставить работать на веб-сайте С#?

Спасибо


person mooncat69    schedule 18.06.2014    source источник
comment
Почему вы использовали SetLastError = true? И почему вы использовали CharSet.Ansi?   -  person David Heffernan    schedule 19.06.2014
comment
Я не уверен насчет SetLastError = true, но пример кода VB определил вызов как Declare Ansi Function GetVersion Lib "ThirdPartyAPI.dll" () As Integer, и этот код работает.   -  person mooncat69    schedule 19.06.2014
comment
Функция не имеет текстовых параметров, поэтому кодировка не имеет значения.   -  person David Heffernan    schedule 19.06.2014


Ответы (1)


Код ошибки 0x8007045A. Это код ошибки COM, который соответствует коду ошибки Win32 ERROR_DLL_INIT_FAILED. Что описывается как:

Ошибка процедуры инициализации библиотеки динамической компоновки (DLL).

Это означает, что ваша DLL была найдена, несмотря на возможно вводящий в заблуждение класс исключений DllNotFoundException. Однако DLL не удалось загрузить. Вы не можете получить больше информации от системы. В библиотеке DLL нет механизма для сообщения о причинах, по которым ее не удалось загрузить. Я предлагаю вам связаться с поставщиком DLL и попросить поддержки.

person David Heffernan    schedule 19.06.2014