将 C++ 非托管代码转换为 C#

罗宾·普比亚

我正在尝试使用 Marshal 在 C# 中获得以下工作 C++ DLL 代码。它有两个结构体,它们在导出的 API 中作为指针参数传递,但它在 C# 中给出的结构体响应值的顺序不正确。而它在 VC++ 中运行良好。

//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。现在,数组第一个元素被正确填充。但是结构数组的其余七个元素没有被填满。

如果有人可以帮助我,如何创建具有顺序内存的所有元素的结构数组。

罗宾·普比亚

最终通过以下更新的结构 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;
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章