我试图从C#中调用用C ++编写的自定义DLL中的函数。但是,我在代码分析期间收到警告,并在运行时收到错误:
警告:CA1400: Microsoft.Interoperability:正确 宣言 '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。
我相信我只是忽略了一些事情......
提前致谢。
答案 0 :(得分:4)
嗯,您知道入口点名称,使用[DllImport]属性中的EntryPoint =“?SetHook @@ YA_NXZ”属性。或者在C ++代码中的声明之前放置extern“C”,这样名称就不会受到损坏。
[DllImport("wi.dll", EntryPoint = "?SetHook@@YA_NXZ", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAsAttribute(UnmanagedType.I1)]
internal static extern bool SetHook();
答案 1 :(得分:1)
CallingConvention.Cdecl
表示C不是C ++,所以当你有一个带有C ++装饰名称的函数时,你需要使用装饰名称作为EntryPoint
或在C ++代码声明中使用Extern“C”关闭C ++名称装饰。