2010-06-08 29 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