2010-06-08 52 views
2

我必须从C#程序中调用C++ DLL。 我尝试使用的PInvoke做到这一点 - 所有的功能都VS2005 \ 2008很好,但移植到VS 2010后,我得到这个异常:VS2010中的元帅结构指针

检测

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的,而不是裁判SInfo,但得到相同的结果...

任何帮助将不胜感激,

谢谢大家!

回答

2

很难看到这可能以前如何工作。 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); 
1

这可能与您的包装结构有关。默认的包大小是8,所以它可能认为你有太多的字节。尝试将包大小设置为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是包装

一个很好的参考
+0

这不可能是,指向结构的指针被传递。 – 2010-06-08 17:24:27