Невозможно вызвать запись импорта DLL, C # -> C ++, EntryPointNotFoundException - PullRequest
0 голосов
/ 17 марта 2010

Я пытаюсь вызвать из C # функцию в пользовательской DLL, написанной на C ++. Однако я получаю предупреждение во время анализа кода и ошибку во время выполнения:

Предупреждение: CA1400: Microsoft.Interoperability: исправить декларация SafeNativeMethods.SetHook (), чтобы это правильно указывает на существующий точка входа в 'wi.dll'. Неуправляемый имя точки входа в настоящее время связано с такое SetHook.

Ошибка: System.EntryPointNotFoundException было необработанный. Невозможно найти запись точка с именем «SetHook» в DLL «wi.dll».

Оба проекта wi.dll и C # exe были скомпилированы в одну и ту же папку DEBUG, оба файла находятся здесь. Во всей файловой системе есть только один файл с именем wi.dll.

Определение функции C ++ выглядит так:

#define WI_API __declspec(dllexport)
bool WI_API SetHook();

Я могу увидеть экспортированную функцию, используя Dependency Walker:

as decorated: bool SetHook(void)
as undecorated: ?SetHook@@YA_NXZ

Импорт C # DLL выглядит так (я определил эти строки, используя CLRInsideOut из журнала MSDN):

[DllImport("wi.dll", EntryPoint = "SetHook", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAsAttribute(UnmanagedType.I1)]
internal static extern bool SetHook();

Я также пробовал без определений EntryPoint и CallingConvention.

Оба проекта 32-битные, я использую W7 64 бит, VS 2010 RC.

Я считаю, что я просто что-то упустил ....

Заранее спасибо.

Ответы [ 2 ]

4 голосов
/ 17 марта 2010

Ну, вы знаете имя точки входа, используйте свойство EntryPoint = "? SetHook @@ YA_NXZ" в атрибуте [DllImport]. Или поместите extern "C" перед объявлением в вашем коде C ++, чтобы имя не было искажено.

[DllImport("wi.dll", EntryPoint = "?SetHook@@YA_NXZ", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAsAttribute(UnmanagedType.I1)]
internal static extern bool SetHook();
1 голос
/ 18 марта 2010

CallingConvention.Cdecl означает C, а не C ++, поэтому, когда у вас есть функция с декорированным именем C ++, вам нужно использовать декорированное имя в качестве EntryPoint или использовать Extern «C» в объявлении кода C ++, чтобы отключить C ++ название украшения.

...