2013-11-25 2 views
3

Мне что-то не хватает; я схожу с ума .. Я использую VS2010 C#, разрабатывая приложение Windows Form на C#. В том же решении у меня есть проект dll C++, который выводит его DLL в ту же папку «/ bin /», что и исполняемый файл C#. Я смотрю на папку, и файл определенно существует. Я даже использовал следующее, чтобы убедиться, что существовали во время выполнения:Неуправляемая DLL не загружается с помощью DLLImport C#

// yep.. it's there... 
string s = System.IO.Directory.GetCurrentDirectory() + @"\Foo.dll"; 
System.Diagnostics.Debug.Assert(System.IO.File.Exists(s)); 

моя DLL имеет это:

extern "C" __declspec(dllexport) int test_func(); 

который подтвердил я с утилитой DLL проводника, чтобы иметь правильное название внутри. Сама функция ничего не делает, кроме «return 4;»

C# код:

[DllImport("Foo.dll")] 
private static extern int test_func(); 

Я получаю эту ошибку:

Необработанное исключение типа 'System.DllNotFoundException' произошло в .exe

Дополнительная информация: Не удается загрузить DLL " Foo.dll ': неверный доступ к ячейке памяти. (Исключение из HRESULT: 0x800703E6)

+0

- ваше приложение ... 32-битное или 64-битное? –

+0

32bit. Или я должен сказать, что я не явным образом определяю 64-битное приложение. – Ben

ответ

2

Ошибка возникает, когда фреймворк вызывает LoadLibrary. Это может быть выведено из сообщения об ошибке:

Unable to load DLL 'Foo.dll'

код ошибки, который сообщается является COM код ошибки, который оборачивает Win32 код ошибки 998, он же ERROR_NOACCESS. Сценарий, который приводит к вызову LoadLibrary метания ERROR_NOACCESS описано здесь: http://support.microsoft.com/kb/196069

SYMPTOMS

The LoadLibrary() API may sometimes encounter an access violation while attempting to map a specified module into the address space of the calling process. In this event, LoadLibrary() returns a value of NULL and GetLastError() returns an error code of 998 (ERROR_NOACCESS). Back to the top | Give Feedback

CAUSE

The Windows NT status code STATUS_ACCESS_VIOLATION is mapped to the Win32 error code ERROR_NOACCESS. As a result, if the operating system loader encounters an access violation (exception C0000005) while mapping the specified DLL file image or executing the startup code, the loader will set the last error to 998 (ERROR_NOACCESS) and the LoadLibrary() function will fail with a return value of NULL. Back to the top | Give Feedback

MORE INFORMATION

When an access violation occurs anywhere in the startup code, the exception dispatcher detects whether the process that encountered this exception is being debugged. If so, this first chance exception is sent to the debugger.

To troubleshoot the LoadLibrary() failure, run the application under a debugger and enable first chance exception handling for the C0000005 Access Violation exception. If an access violation occurs when the LoadLibrary() function is called, the application will break into the debugger. The debugger's call stack can then be used to trace where the exception occurred. The stack trace should help you narrow down the actual problem related to the exception being encountered.

For information on how to enable first chance exception handling for the C0000005 Access violation exception, please refer to the debugger documentation.

В сущности, ваша DLL вызывает нарушение доступа в его код запуска. Это может привести ко многим вещам, и вам потребуется выполнить некоторую отладку DLL. Я предлагаю вам попробовать отладить это с собственного C++-хоста. Скорее всего, будет легче отлаживать DLL таким образом.

Как и в стороне, ваша функция использует соглашение о вызове cdecl, и как только вы пройдете текущее препятствие, вам нужно будет изменить свой C# p/invoke, чтобы указать CallingConvention.Cdecl.

+0

Я использовал DllImport [] в LoadLibrary из моего приложения C# и называет его возвращенным «0». ?!? Я использовал тот же самый путь, который я использовал с File.Exists(), поэтому я думаю, что это должна быть какая-то проблема с разрешениями. – Ben

+0

Нет. Он возвращает 'LoadLibrary' возвращает' 0', когда он терпит неудачу. Это указывает на ошибку.Если вы включите 'SetLastError = true' в pinvoke' LoadLibrary', вы можете вызвать 'Marshal.GetLastWin32Error', и он вернет 998. Это не разрешения. DLL 'DllMain' вызывает нарушение доступа. Следующий шаг - сделать то, что я сказал. Отлаживайте это с помощью собственного хоста. Или выясните, как включить неуправляемую отладку с вашего хоста C#. –

+0

О, человек, которого я не видел, этот грядущий ... глобальный статический класс обращался к своему собственному члену «static std :: map <>». Но похоже, что к нему обращались до определения члена. Я предполагаю, что он каким-то образом не инициализировал его собственные значения во времени, которые будут использоваться конструктором. Я даже не думал, что это возможно! Я переупорядочил код, и теперь он работает .. сумасшедший. – Ben

0

Предполагается, что вы уже видели this link.

Вы открыли «foo.dll» с помощью depends.exe, чтобы убедиться, что у вас есть все зависимости?

+0

DLL ничего не делает. Это зависит только от пары stl шаблонов. Я запустил файл depend.exe и получил только это: Ошибка: хотя бы один модуль имеет неразрешенный импорт из-за отсутствия функции экспорта в неявно зависимом модуле. Ошибка: были найдены модули с различными типами ЦП. Я предполагаю, что он жалуется, потому что DLL 32bit, и я запускаю Windows 7 x64. – Ben

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