C# 在.NET 4中使用IntPtr时出现PinVokesTack异常?(在.NET 3.5中工作)
这可能是一个很难回答的问题,但在过去的几个小时(或几天)里,这件事让我陷入了困境 我在.NETFramework4.0中的代码中从DLL调用一个方法C# 在.NET 4中使用IntPtr时出现PinVokesTack异常?(在.NET 3.5中工作),c#,.net,c#-4.0,c#-3.0,intptr,C#,.net,C# 4.0,C# 3.0,Intptr,这可能是一个很难回答的问题,但在过去的几个小时(或几天)里,这件事让我陷入了困境 我在.NETFramework4.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, X
[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)
然而,当我在.NET4.0中运行这个程序时,我得到了一个p/INVOKE错误,然而。。。在3.5中运行此操作不会触发此错误。在我和另一个程序员检查了代码之后,我们似乎把它归结为在4.0上运行不同的IntPtr
我的应用程序需要在.NET4.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签名的调用约定和参数是否与目标非托管签名匹配。在我的脑海中,您是否检查了这两个项目的细节?如果一个是64位,另一个是32位,则会出现错误。请注意,在最新版本中,C#项目的默认值从任何CPU更改为x86。这在x86操作系统上并不重要,但在x64操作系统上,这会产生显著的差异
此外,您通常应该尽可能多地包含错误文本,审查以保护私人信息是可以的,但是错误编号和文本可能非常有用。此外,在使用
extern
时,最好包含任何struct
类型的两个定义,以确保它们是等效的。(另一个常见问题)。这有两个常见原因:
stdcall
。本机代码可能使用cdecl
。尝试将CallingConvention=CallingConvention.Cdecl
添加到DllImport
属性中< >您的C++虚拟方法的本机定义为:
virtual ErrCode XCamera::GetFrame(FrameType type, unsigned long ulFlags,
void * buffer, unsigned int size);
看起来您正在将对象指针作为pinvoke调用中的第一个参数传递。我认为这是可行的,尽管我对导出时如何处理虚拟函数的了解还不够,不知道这是否是一个问题。大概您已经导出了一个普通的C函数来实例化对象
我看到的另一个问题是,在Windows上,C/C++
long
是32位的。C#长
是64位。这意味着ulFlags
的正确声明是在您的C#code中的uint
。也许更好的问题是为什么它以前有效。你提供的声明:
virtualerrcode XCamera::GetFrame(FrameType类型,无符号长字符串,void*缓冲区,无符号整数大小)
具有与以下项相对应的.NET类型:FrameType、uint、IntPtr、uint
在Windows上,
unsigned long
是32位类型,而在C#ulong
中是64位类型。XC#u GetFrame的本机定义是什么,您遇到的错误是什么?请解释您得到的错误是什么?定义:virtual ErrCode XCamera::GetFrame(FrameType类型,无符号长字符串,void*缓冲区,无符号整数大小)[纯虚拟]错误是PINVOKE堆栈Imabalance:调用PINVOKE函数“DLLTest!DLLTest.Form1::XC_GetFrame”使堆栈不平衡。您的代码在.net 2中已经有一个错误的导入签名,但该版本过于宽松,出现了某些错误。net 4更为严格,公开(而不是导致)错误。两个项目都在32位下运行,所有关联的DLL也在32位下运行…调试时我收到的错误是:PinVokeStackDistribution:调用PInvoke函数“DLLTest!DLLTest.Form1::XC_GetFrame”使堆栈不平衡。这可能是因为托管PInvoke签名与非托管目标不匹配签名。检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配。函数定义:virtual ErrCode XCamera::GetFrame(FrameType类型,无符号长ulFlags,void*缓冲区,无符号整数大小)[纯虚拟]不可能是这样。当有一点不匹配时,您无法调用函数。@DavidHeffernan:由于缺少错误消息,我不确定其他DLL何时会加载到内存中。将调用约定添加到DLLImport属性中,仍然得到相同的错误。我列出了本机函数声明吗n在另一个答案中是否正确?另外,如果框架设置为3.5,应用程序将正常运行,但正如您所说的,代码可能会被破坏。更新原始帖子以包含声明:)我猜想使用PInvoke调用与:使用System.Runtime.InteropServices?当你调用一个带有DllImport属性的函数时,那就是pinvoke.Updated ulflags以键入uint,但是这个应用程序中从同一个DLL调用的其他方法仍然有效;我很确定是C++方法……HyDA6963我想我已经把它讲过头了。我怀疑您可以通过p援引调用C++方法。除了通过必须导出的帮助器函数之外,您不能实例化C++对象。我想你已经这么做了。我真的不知道虚拟方法是如何与pinvoke一起工作的。你…吗?否则,您需要修复长时间的不匹配,并使调用约定正确。