[英]PInvokeStackImbalance exception when using IntPtr in .NET 4? (Works in .NET 3.5)
可能會有一點菜鳥的問題,但這是讓我在過去幾個小時(或幾天)的泡菜中得到的東西......
我在.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簽名的調用約定和參數是否與目標非托管簽名匹配。
兩個常見原因:
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位。 AC# long
是64位。 這意味着ulFlags
的正確聲明在C#代碼中是uint
。
在我的腦海中,您是否檢查了兩個項目的位置? 如果一個是64位而另一個是32位,則會出錯。 請注意,在最近的版本中,C#項目的默認值從Any CPU更改為x86。 這在x86操作系統上無關緊要,但在x64操作系統上它會產生重大影響。
此外,您通常應盡可能多地包含錯誤文本,審查以保護私人信息是正常的,但錯誤號和文本可能非常有用。 此外,在使用extern
時,包含任何struct
類型的兩個定義以確保它們是等效的是有幫助的。 (另一個常見問題)。
也許一個更好的問題是它之前有效的原因。 您提供的聲明:
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位類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.