2017-06-20 51 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; 
}