问题描述
可能有点菜鸟问题,但在过去的几个小时(或几天)里,这让我一直在泡菜中...
Might be a bit of noob question but it's something that's been getting me in a pickle for the past few hours (or days)...
在.NET Framework 4.0中的代码中从DLL调用方法
I'm calling a method from a DLL in my code in .NET Framework 4.0
[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。
However, when I run this in .NET 4.0 I get a P/INVOKE error, however... running this in 3.5 does not trigger this error. After myself and another programmer have gone over the code we seem to have put it down to the IntPtr running differently on 4.0.
我的应用程序需要在.NET 4.0中运行该应用程序所需的几个功能仅在4.0中可用...
My application needs to run in .NET 4.0 as a couple of features required by the application are only available in 4.0 ...
是否存在我可能忽略的东西或只是忘记包含了什么?
Is there anything that maybe i'm overlooking or have simply forgotten to include?
任何想法都值得赞赏!
汤姆
更新:
本机声明:
virtual ErrCode XCamera::GetFrame(FrameType type, unsigned long ulFlags, void *buffer, unsigned int size)
错误:调用PInvoke函数'DLLTest!DLLTest.Form1 :: XC_GetFrameType'已使堆栈不平衡。这可能是因为托管PInvoke签名与非托管目标签名不匹配。检查PInvoke签名的调用约定和参数是否与目标非托管签名相匹配。
Error: A call to PInvoke function 'DLLTest!DLLTest.Form1::XC_GetFrameType' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.
推荐答案
出现此问题的两个常见原因:
Two common causes for this:
- 调用约定不匹配。您的C#代码使用默认的
stdcall
。也许本地代码使用cdecl
。尝试将CallingConvention = CallingConvention.Cdecl
添加到DllImport
属性。 - 不匹配参数列表(请参见下文)。
- Mismatch of calling conventions. Your C# code uses the default of
stdcall
. Perhaps the native code usescdecl
. Try addingCallingConvention=CallingConvention.Cdecl
to theDllImport
attribute. - Mismatch of parameter lists (see below).
不要自欺欺人,因为.net 3.5不会引发此问题错误。 .net 4中的错误检测更好,这就是为什么您仅在其中看到错误的原因。但是您的代码在所有.net版本中都是损坏的。
Don't kid yourself that your code is alright because .net 3.5 doesn't raise this error. The error detection in .net 4 is better which is why you only see the errors there. But your code is broken in all .net versions.
C ++虚拟方法的本机定义是:
The native definition for your C++ virtual method is:
virtual ErrCode XCamera::GetFrame(FrameType type, unsigned long ulFlags,
void * buffer, unsigned int size);
看起来您正在将对象指针作为pinvoke调用中的第一个参数传递。我认为这可行,尽管我对导出虚拟函数时的处理方式还不了解,以了解是否存在问题。大概您已经导出了一个普通的C函数来实例化对象。
It looks like you are passing the object pointer as the first parameter in your pinvoke call. I think that could work, although I don't know enough about how virtual functions are handled when exported to know whether that's a problem. Presumably you have exported a plain C function to instantiate objects.
我看到的另一个问题是在Windows上C / C ++的 long
是32位。 C# long
是64位。这意味着 ulFlags
的正确声明是C#代码中的 uint
。
The other problem that I see is that on Windows, C/C++ long
is 32 bits. A C# long
is 64 bits. This means that the correct declaration for ulFlags
is as uint
in your C# code.
这篇关于在.NET 4中使用IntPtr时出现PInvokeStackImbalance异常? (在.NET 3.5中有效)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!