2017-06-20 108 views
0

我想在C#中使用元帥的C++ DLL代碼下面工作。 它有兩個結構在傳出的API中作爲指針參數傳遞,但它在C#中發出的結構響應值的順序不正確。而它在VC++中工作正常。將C++非託管代碼轉換爲C#

//C++ Code - Working 
//Structure 1 
typedef struct 
{ 
    bool bExist; 
    bool bAvailable; 
    int  iNoteNumber; 
    int  iDispenseNumber; 
    int  iOutNoteNumber; 
    char cStatus; 
    char acBoxID[6]; 
} tHopperStatus; 
//Structure 2 
typedef struct 
{ 
    char acCurrency[4]; 
    int lDenomination; 
    int iRemainCount; 
    int iCount; 
    int iOutCount; 
    int iRejectCount; 
    int iPurgeCount;  
    BYTE byHopper; 
    char cStatus; 
    char cLastStatus;  
    char acBoxID[6]; 
    BYTE byBoxType; 
    char acReserved1[10]; 
    char acReserved2[10]; 
    int iReserverd1; 
    int iReserverd2; 
} tCashBox; 
//API using above two structures 
int iGetCassette(tCashBox* p_psCashBox,tDevReturn* p_psStatus); 

//Calling API by passing pointer of Structure Array 
tCashBox l_asBox[8] = {0}; 
tDevReturn l_asReturn[8] = {0}; 
int l_iRes = l_pDev->iGetCassette(l_asBox, l_asReturn); 

我在C#中實現什麼:

//C# Code 
//Structure 1 
[StructLayout(LayoutKind.Sequential)] 
unsafe public struct tDevReturn 
{ 
    public tDevReturn(int param) 
    { 
     iLogicCode = 0; 
     iPhyCode = 0; 
     iHandle = 0; 
     iType = 0; 
     acDevReturn = new char[128]; 
     acReserve = new char[128]; 
    } 
    public int iLogicCode; 
    public int iPhyCode; 
    public int iHandle; 
    public int iType; 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] 
    public char[] acDevReturn; 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] 
    public char[] acReserve; 
} 
//Structure 2 
[StructLayout(LayoutKind.Sequential)] 
unsafe public struct tCashBox 
{ 
    public tCashBox(int param) 
    { 
     acCurrency = new char[4]; 
     lDenomination = 0; 
     iRemainCount = 0; 
     iCount = 0; 
     iOutCount = 0; 
     iRejectCount = 0; 
     iPurgeCount = 0; 
     byHopper = 0; 
     cStatus = '\0'; 
     cLastStatus = '\0'; 
     acBoxID = new char[6]; 
     byBoxType = 0; 
     acReserved1 = new char[10]; 
     acReserved2 = new char[10]; 
     iReserverd1 = 0; 
     iReserverd2 = 0; 
    } 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] 
    public char[] acCurrency; 
    public long lDenomination; 
    public int iRemainCount; 
    public int iCount; 
    public int iOutCount; 
    public int iRejectCount; 
    public int iPurgeCount; 
    public byte byHopper; 
    public char cStatus; 
    public char cLastStatus; 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] 
    public char[] acBoxID; 
    public byte byBoxType; 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] 
    public char[] acReserved1; 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] 
    public char[] acReserved2; 
    public int iReserverd1; 
    public int iReserverd2; 
} 

//API Import Declaration 
[DllImport("xxxxxxxxxx.dll", CallingConvention = CallingConvention.StdCall)] 
public static extern int CDM_iGetCassette([In, Out] tCashBox[] p_psCashBox, [In, Out] tDevReturn[] p_psStatus); 

//API Call - but filling up the structure array with random values and incorrect sequence 
tDevReturn[] response = new tDevReturn[8]; 
tCashBox[] cashboxData = new tCashBox[8]; 
int ret = Wrapper.CDM_iGetCassette(cashboxData, response); 

我有一個疑問,這樣結構的傳球達陣是否允許或不允許在C#中,其中在C++中,它是工作。如果有人能幫助我,這將是一個很大的幫助。提前致謝。我編輯: 我改變'lDenomination'的數據類型從long到int。現在,數組的第一個元素正在被填滿。但結構數組剩餘的七個元素沒有被填滿。

如果有人可以幫助我,如何創建具有所有有序內存的元素的結構數組。

+0

更改簽名: 公共靜態外部INT CDM_iGetCassette(出tCashBox []錢櫃,出...) –

+0

而你並不需要不安全的結構。你可以在安全上下文 –

+0

中使用'out'關鍵字而不是'[In,Out]'給出指針和內存異常。 @VahidK。 –

回答

0

最終解決了這個問題,下面更新了結構2: 1.將'lDenomination'的數據類型從long更改爲int。 2.在結構佈局參數中添加Pack = 1和CharSet = CharSet.Ansi。

[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 
public struct tCashBox 
{ 
    public tCashBox(int param) 
    { 
     acCurrency = new char[4]; 
     lDenomination = 0; 
     iRemainCount = 0; 
     iCount = 0; 
     iOutCount = 0; 
     iRejectCount = 0; 
     iPurgeCount = 0; 
     byHopper = 0; 
     cStatus = '\0'; 
     cLastStatus = '\0'; 
     acBoxID = new char[6]; 
     byBoxType = 0; 
     acReserved1 = new char[10]; 
     acReserved2 = new char[10]; 
     iReserverd1 = 0; 
     iReserverd2 = 0; 
    } 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] 
    public char[] acCurrency; 
    public int lDenomination; 
    public int iRemainCount; 
    public int iCount; 
    public int iOutCount; 
    public int iRejectCount; 
    public int iPurgeCount; 
    public byte byHopper; 
    public char cStatus; 
    public char cLastStatus; 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] 
    public char[] acBoxID; 
    public byte byBoxType; 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] 
    public char[] acReserved1; 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] 
    public char[] acReserved2; 
    public int iReserverd1; 
    public int iReserverd2; 
}