从.NET1.1升级到.NET2.0时出现的PInvokeStackImbalance错误

原创 2006年05月29日 17:29:00

.NET1.1升级到.NET2.0时出现的PInvokeStackImbalance错误

 

微软官方的解释 (http://msdn2.microsoft.com/zh-cn/library/0htdy0k3.aspx)

如果 CLR 检测到平台调用之后的堆栈深度与 DllImportAttribute 属性指定的调用约定中以及托管签名的参数声明中提供的预期堆栈深度不匹配,则将激活 PInvokeStackImbalance 托管调试助手 (MDA)

 

下面将举一个具体的例子

PCCamera(UserLib.Device.PCCamera摄像头类)在从.NET1.1级到.NET2.0时出现的PInvokeStackImbalance错误:

检测到 PInvokeStackImbalance

Message: PInvoke 函数“WindowsApplication1!UserLib.Device.PCCamera::SendMessage”的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。

错误首次发生在这一行代码: SendMessage(hWndC, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, 0);

经过分析发现所有调用SendMessage函数的地方都会出现以上错误

于是查看DLLImport:

[DllImport("User32.dll")]

private static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, long lParam);

原来是因为WinAPIlong类型是32位的,C#long64位的,这就导致堆栈不对称,引发错误.

 

原因: (http://discuss.develop.com/archives/wa.exe?A2=ind0512c&L=dotnet-winforms&D=0&T=0&P=8094)

.NET2.0中加入了MDA(managed debugging assistant), 在平台调用时后会检查栈的指针, 如果发现不平衡, 就会抛出PInvokeStackImbalance异常; 而在.NET1.1中不会检查, 所以不会捕获到异常, 但在运行时会导致不稳定.

 

解决方法:

将最后一个long lParam改为 int wParam”, 因为C#int32位的. 并且将之后有涉及到SendMessage函数的参数适当地转成int型就可以了.

但是, 之后查阅了资料http://www.pinvoke.net/default.aspx/user32/SendMessage.html

发现先前的解决方案还有不合适的地方, 应该将其中的 ”wParm” ”lParm” 参数的类型都转成IntPtr类型,并且将后面涉及到的参数的 ”0”改为 “IntPtr.Zero”. 因为如果使用int类型,那么这段代码在64位的Windows上面将会无法正常运行.

 

总结:

       我们在调用WinAPI时要特别小心, 因为WinAPIC#的数据类型不是完全一样, 就好像在WinAPI中的long类型在C#中就是int类型, 如果没有处理好类型问题, 就很可能会导致堆栈的不平衡,引发PInvokeStackImbalance错误, 但是这类错误在.NET1.1下不会被暴露出来, 所以在从.NET1.1级到.NET2.0时要特别注意此类问题.

 

C# .NET4.0 改为 到.NET2.0 报错解决方法

如今的VS开发工具都是VS2012或者VS2015版本,高版本开发的程序默认使用的都是.NET4.0或者更高的框架,其他电脑在运行该程序时需要安装对应版本的.NET。目前winXP和Win7系统默认都...
  • yinjun151
  • yinjun151
  • 2016年05月24日 17:30
  • 1909

ubuntu 14.04升级16.04 遇到的相关问题及解决

安装ROS时,程序报错:***@bw-CW35:~$ sudo apt-get install ros-kinetic-desktop-full [sudo] *** 的密码: 正在读取软件包列表....
  • jayandchuxu
  • jayandchuxu
  • 2017年04月17日 09:05
  • 1247

Ubuntu:dpkg更新管理器出错及解决

【问题描述】 cvsd 已经是最新的版本了。 升级了 0 个软件包,新安装了 0 个软件包,要卸载 0 个软件包,有 0 个软件包未被升级。 有 5 个软件包没有被完全安装或卸载。 解压缩后会消耗掉 ...
  • he_qiao_2010
  • he_qiao_2010
  • 2013年12月22日 18:27
  • 1594

从VS2003(.net1.1)升级到vs2005(.net2.0)全程跟踪记录

[项目背景介绍]   本文要升级的项目是我公司目前的一个电子商务门户站点,系统极其复杂,2004年做成这个系统,几年来不断变迁,代码日积月累,产生了许多无用或重复性的代码,光UI版面就已经更新过...
  • sunway888
  • sunway888
  • 2012年05月14日 02:52
  • 459

ASP.NET1.1、ASP.NET2.0、ASP.NET3.5中验证控件等问题

在asp.net页面中,当有验证控件,而且想在验证控件验证通过之后,弹出一个确认对话框,提示是否继续。 当在button按钮上添加客户端的onclick="return confirm('Are y...
  • demo1573
  • demo1573
  • 2015年09月15日 17:05
  • 149

[VS2010].NET4.0环境下使用.NET2.0程序集,出现“混合模式程序集异常”

今天在把以前写的代码生成工具从原来的.NET3.5升级到.NET4.0,同时准备进一步完善,将程序集都更新后,一运行程序在一处方法调用时报出了一个异常: 混合模式程序集是针对“v2.0.5072...
  • dragon_ton
  • dragon_ton
  • 2016年03月19日 10:36
  • 968

[VS2010].NET4.0环境下使用.NET2.0程序集,出现“混合模式程序集异常”

今天在把以前写的代码生成工具从原来的.NET3.5升级到.NET4.0,同时准备进一步完善,将程序集都更新后,一运行程序在一处方法调用时报出了一个异常: 混合模式程序集是针对“v2.0.50...
  • leowangzi
  • leowangzi
  • 2012年03月27日 21:48
  • 2930

[VS2010].NET4.0环境下使用.NET2.0程序集,出现“混合模式程序集异常”

转自:http://www.cnblogs.com/kyo-yo/archive/2010/08/19/VS2010-Use-NET2-In-NET4.html 今天在把以前写的代码生成工具从原来的...
  • ArvinStudy
  • ArvinStudy
  • 2012年07月09日 14:21
  • 656

Dreamershop梦想家网店系统V3.0(免费完整版)升级到.NET4.0

  • 2011年11月13日 18:22
  • 19.87MB
  • 下载

将 Visual Basic 6.0 应用程序升级到 Visual Basic .NET 和 Visual Basic 2005

  • 2009年01月03日 21:09
  • 85KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:从.NET1.1升级到.NET2.0时出现的PInvokeStackImbalance错误
举报原因:
原因补充:

(最多只允许输入30个字)