无法调用 DLL 导入入口,C# -> C++,EntryPointNotFoundException
我正在尝试从 C# 调用用 C++ 编写的自定义 DLL 中的函数。但是,我在代码分析期间收到警告,并在运行时收到错误:
警告:CA1400: Microsoft.互操作性:正确 的声明 'SafeNativeMethods.SetHook()' 这样 它正确地指向现有的 “wi.dll”中的入口点。无人管理的 当前链接到的入口点名称 是SetHook。
错误: System.EntryPointNotFoundException 是 未处理的。找不到条目 DLL“wi.dll”中名为“SetHook”的点。
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 导入如下所示(我使用 MSDN 杂志中的 CLRInsideOut 定义了这些行):
[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。
我相信我只是忽略了一些东西......
提前致谢。
I'm trying to call from C# a function in a custom DLL written in C++. However I'm getting the warning during code analysis and the error at runtime:
Warning: CA1400 :
Microsoft.Interoperability : Correct
the declaration of
'SafeNativeMethods.SetHook()' so that
it correctly points to an existing
entry point in 'wi.dll'. The unmanaged
entry point name currently linked to
is SetHook.Error:
System.EntryPointNotFoundException was
unhandled. Unable to find an entry
point named 'SetHook' in DLL 'wi.dll'.
Both projects wi.dll and C# exe has been compiled in to the same DEBUG folder, both files reside here. There is only one file with the name wi.dll in the whole file system.
C++ function definition looks like:
#define WI_API __declspec(dllexport)
bool WI_API SetHook();
I can see exported function using Dependency Walker:
as decorated: bool SetHook(void)
as undecorated: ?SetHook@@YA_NXZ
C# DLL import looks like (I've defined these lines using CLRInsideOut from MSDN magazine):
[DllImport("wi.dll", EntryPoint = "SetHook", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAsAttribute(UnmanagedType.I1)]
internal static extern bool SetHook();
I've tried without EntryPoint and CallingConvention definitions as well.
Both projects are 32-bits, I'm using W7 64 bits, VS 2010 RC.
I believe that I simply have overlooked something....
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好吧,您知道入口点名称,请使用 [DllImport] 属性中的 EntryPoint = "?SetHook@@YA_NXZ" 属性。或者将 extern "C" 放在 C++ 代码中的声明之前,这样名称就不会被破坏。
Well, you know the entry point name, use the EntryPoint = "?SetHook@@YA_NXZ" property in the [DllImport] attribute. Or put extern "C" before the declaration in your C++ code so the name doesn't get mangled.
CallingConvention.Cdecl
表示 C 而不是 C++,因此当您有一个具有 C++ 修饰名称的函数时,您需要使用修饰名称作为您的EntryPoint
或使用 Extern "C"在 C++ 代码声明中关闭 C++ 名称修饰。CallingConvention.Cdecl
means C not C++, so when you have a function with a C++ decorated name, you need to use the decorated name as yourEntryPoint
or use Extern "C" in The C++ code declaration to turn off C++ name decoration.