【发布时间】:2011-01-24 07:51:24
【问题描述】:
切换到 VS2010 后,托管调试助手显示一个错误,即从 C# 应用程序调用非托管 C++ 函数导致堆栈不平衡。
通常的嫌疑人似乎没有导致问题。还有什么我应该检查的吗? VS2008 构建的 C++ dll 和 C# 应用程序从来没有问题,没有奇怪或神秘的错误 - 是的,我知道这并不意味着什么。
检查的内容如下:
- dll 名称正确。
- 入口点名称是正确的,并且已经使用depends.exe 进行了验证 - 代码必须使用经过修改的名称,并且确实如此。
- 调用约定是正确的。
- 大小和类型似乎都正确。
- 字符集正确。
- 忽略错误后似乎没有任何问题,在调试器之外运行时也没有问题。
C#:
[DllImport("Correct.dll", EntryPoint = "SuperSpecialOpenFileFunc", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, ExactSpelling = true)]
public static extern short SuperSpecialOpenFileFunc(ref SuperSpecialStruct stuff);
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public struct SuperSpecialStruct
{
public int field1;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string field2;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
public string field3;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
public string field4;
public ushort field5;
public ushort field6;
public ushort field7;
public short field8;
public short field9;
public uint field10;
public short field11;
};
C++:
short SuperSpecialOpenFileFunc(SuperSpecialStruct * stuff);
struct SuperSpecialStruct
{
int field1;
char field2[256];
char field3[20];
char field4[10];
unsigned short field5;
unsigned short field6;
unsigned short field7;
short field8;
short field9;
unsigned int field10;
short field11;
};
这是错误:
托管调试助手 'PInvokeStackImbalance' 检测到一个 “托管应用程序路径”中的问题。
附加信息:致电 PInvoke 函数 'SuperSpecialOpenFileFunc' 有 堆栈不平衡。这很可能 因为托管的 PInvoke 签名 与非托管目标不匹配 签名。检查调用 公约和参数 PInvoke 签名匹配目标 非托管签名。
【问题讨论】:
-
是的,我也遇到了这个问题,但不知道为什么。你会认为如果调用约定被搞砸了,它只会完全破坏堆栈并且它不会工作。它为我打的每一个电话都声明了这一点。
-
同样的问题,不知道为什么。不过,程序仍然有效。
-
哦,对我来说,将 c++ 函数更改为 __stdcall 解决了问题。
-
从 .NET Framework 4 开始,流线型的互操作封送架构为从托管代码到非托管代码的转换提供了显着的性能改进。在早期版本的 .NET Framework 中,封送层在 32 位平台上检测到不正确的平台调用声明并自动修复堆栈。 this url has explaned this
标签: c# c++ visual-studio-2010 pinvoke dllimport