可能会有一些noob问题,但这是过去几个小时(或几天)让我陷入困境的事情......
我在.NET Framework 4.0的代码中调用DLL的方法
[DllImport("xeneth.dll")]
public static extern ErrorCode XC_GetFrame(Int32 h, FrameType type, ulong ulFlags, IntPtr buff, uint size);
然后在这里使用它:
if (XC_GetFrame(myCam, XC_GetFrameType(myCam), 0, IntPtr.Zero, (uint)fs) != ErrorCode.E_NO_FRAME)
但是,当我在.NET 4.0中运行它时,我得到一个P / INVOKE错误,但是......在3.5中运行它不会触发此错误。在我和另一个程序员完成代码之后,我们似乎把它归结为在4.0上运行不同的IntPtr。
我的应用程序需要在.NET 4.0中运行,因为应用程序所需的一些功能仅在4.0中可用...
有什么东西可能是我忽略或只是忘记包括在内吗?
非常感谢任何想法!
汤姆
更新
原住民声明:
virtual ErrCode XCamera::GetFrame(FrameType type, unsigned long ulFlags, void *buffer, unsigned int size)
错误:对PInvoke函数'DLLTest!DLLTest.Form1 :: XC_GetFrameType'的调用使堆栈失衡。这很可能是因为托管PInvoke签名与非托管目标签名不匹配。检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配。
答案 0 :(得分:9)
两个常见原因:
stdcall
。也许本机代码使用cdecl
。尝试将CallingConvention=CallingConvention.Cdecl
添加到DllImport
属性。不要自欺欺人,因为.net 3.5不会引发此错误。 .net 4中的错误检测更好,这就是为什么你只看到那里的错误。但是你的代码在所有.net版本中都被破坏了。
C ++虚拟方法的本机定义是:
virtual ErrCode XCamera::GetFrame(FrameType type, unsigned long ulFlags,
void * buffer, unsigned int size);
看起来您正在将对象指针作为pinvoke调用中的第一个参数传递。我认为这可行,虽然我不太了解在导出时如何处理虚函数以了解这是否是一个问题。据推测,您已导出一个普通的C函数来实例化对象。
我看到的另一个问题是,在Windows上,C / C ++ long
是32位。 C#long
是64位。这意味着{C}代码中ulFlags
的正确声明为uint
。
答案 1 :(得分:3)
我是否已经检查了两个项目的位置?如果一个是64位而另一个是32位,则会出错。请注意,在最近的版本中,C#项目的默认值从Any CPU更改为x86。这在x86操作系统上无关紧要,但在x64操作系统上它会产生重大影响。
此外,您通常应尽可能多地包含错误文本,审查以保护私人信息是正常的,但错误号和文本可能非常有用。此外,在使用extern
时,包含任何struct
类型的定义以确保它们是等效的很有帮助。 (另一个常见问题)。
答案 2 :(得分:1)
也许一个更好的问题是它之前有效的原因。您提供的声明:
virtual ErrCode XCamera::GetFrame(FrameType type, unsigned long ulFlags, void * buffer, unsigned int size)
的.NET类型对应于:FrameType, uint, IntPtr, uint
。
在Windows上,unsigned long
是32位类型,而在C#ulong
中是64位类型。