无法调用DLL导入条目,C# - > C ++,EntryPointNotFoundException

时间:2010-03-17 19:29:32

标签: winapi pinvoke name-decoration

我试图从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。

我相信我只是忽略了一些事情......

提前致谢。

2 个答案:

答案 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 ++名称装饰。