VS2010中的元帅结构指针
Posted
技术标签:
【中文标题】VS2010中的元帅结构指针【英文标题】:Marshal structure pointer in VS2010 【发布时间】:2010-06-08 16:35:18 【问题描述】:我必须从我的 C# 程序中调用 C++ DLL。 我正在尝试使用 PInvoke 执行此操作 - 在 VS2005\2008 中一切正常,但在迁移到 VS 2010 后,我得到了这个异常:
检测到 PInvokeStackImbalance 消息:调用 PInvoke 函数 “sampleFunc”使堆栈不平衡。 这可能是因为托管 PInvoke 签名与 非托管目标签名。检查 调用约定和参数 PInvoke 签名的匹配 目标非托管签名。
这是最初的 C++ 原型:
typedef struct
unsigned short field1;
unsigned short field2;
sInfo;
_declspec(dllexport) int sampleFunc(sInfo *info, char *txt);
这里是 C# 代码:
[StructLayout(LayoutKind.Sequential)]
struct SInfo
//[MarshalAs(UnmanagedType.U1)] //also tried with the MarshalAs attr. Didn't help.
public ushort field1;
//[MarshalAs(UnmanagedType.U1)]
public ushort field2;
;
[DllImport("sampleModule.dll", CharSet=CharSet.Ansi)]
public static extern int sampleFunc(ref SInfo info, [MarshalAs(UnmanagedType.LPStr)] string txt);
我也尝试过使用 IntPtr 而不是 ref SInfo,但得到了相同的结果...
任何帮助将不胜感激,
谢谢大家!
【问题讨论】:
【参考方案1】:很难看出这在以前是如何发挥作用的。 C++ 声明不声明调用约定,默认为 __cdecl,除非在 C++ 项目中使用 /Gz 编译选项覆盖。你必须告诉 P/Invoke 编组器:
[DllImport("sampleModule.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern int sampleFunc(ref SInfo info, string txt);
【讨论】:
【参考方案2】:这可能与你如何打包结构有关。默认的包大小是 8,所以它可能认为你有太多字节。尝试将 Pack 大小设置为 2(16 位对齐),看看是否有帮助:
[StructLayout(LayoutKind.Sequential, Pack=2)]
您也可以像这样指定偏移量:
[StructLayout(LayoutKind.Explicit)]
public struct struct1
[FieldOffset(0)]
public ushort a; // 2 bytes
[FieldOffset(2)]
public ushort b; // 2 bytes
Here是一个很好的打包参考
【讨论】:
以上是关于VS2010中的元帅结构指针的主要内容,如果未能解决你的问题,请参考以下文章