Невозможно вызвать запись импорта DLL, C# -> C++, EntryPointNotFoundException

StackOverflow https://stackoverflow.com/questions/2465243

  •  20-09-2019
  •  | 
  •  

Вопрос

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

Предупреждение:СА1400:Microsoft.Интероперабельность:Исправьте объявление «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-битные, я использую 64-битную версию W7, VS 2010 RC.

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

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

Это было полезно?

Решение

Итак, вы знаете имя точки входа, используйте свойство 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();

Другие советы

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top