簡體   English   中英

C#中調用C ++ DLL函數時傳遞結構

[英]passing structure when calling C++ DLL function in C#

我需要使用C#來控制具有C ++ DLL的測試模塊,以下是最初在C ++頭文件中定義的結構和初始化函數

typedef unsigned char       uint8_t;
typedef unsigned long       uint32_t;
typedef unsigned short      uint16_t;
typedef unsigned char       bool_t;
typedef signed short        int16_t;
typedef signed char         int8_t;
typedef signed long         int32_t;

#define ER      0x2
#define BS      0x4000

typedef enum {
    nI2C,
    nSPI,
    nUSB,
    nSDIO
} mBus;

typedef uint8_t cAddr; 

typedef enum {
    nCPHA0=0,
    nCPHA1
} mPhase;

typedef enum {
    nCPOL0=0,
    nCPOL1
} mSpiPol;

typedef struct {
    mPhase cPha;
    mSpiPol cPol;
} mSpiCfg;

typedef struct {
    uint8_t             xo; 
    bool_t              init_bus_only;                          
    uint32_t            zone; 
    mBus             bustype;  
    mBus             transporttype; 
    cAddr         i2cAddr;
    mSpiCfg          spiCfg;
    bool_t              use_pmu; 
} mInitCfg;

typedef enum {
    OK = 0,
    FAIL = -1,  
    BUS_ALREADY_LOADED = -2,
    BUS_TYPE_UNKNOWN = -3,
    BUS_LOAD_LIBRARY_FAIL = -4,
    BUS_GET_PROC_FAIL = -5,
    BUS_INIT_FAIL = -6,
    Err_CHIP_INIT = -7
} retCode;

typedef struct {
    mInitCfg cfg;
} mDrvIn;

__declspec(dllexport) retCode cp_init(mDrvIn * inp);

在C ++中,其名稱如下

static void init(void)
{
mDrvIn di;
retCode rc;

memset(&di, 0, sizeof(mDrvIn));

di.cfg.bustype = nI2C; 
di.cfg.init_bus_only = 1;
di.cfg.transporttype = di.cfg.bustype;
di.cfg.zone = ER | BS;

    rc = cp_init(&di);
    if(rc < 0) {
    printf("Failed to initialize. Error code %d: %s", rc, to_string(rc));
    return;
}
}

我在調用DLL函數時使用下面的C#結構

using cAddr = System.Byte;
public enum mBus
{
    nI2C,
    nSPI,
    nUSB,
    nSDIO
};

public enum mPhase
{
    nCPHA0 = 0,
    nCPHA1
};

public enum mSpiPol
{
    nCPOL0 = 0,
    nCPOL1
};

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct mSpiCfg
{
    public mPhase cPha;
    public mSpiPol cPol;
};

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct mInitCfg
{
    public byte xo; 
    public byte init_bus_only; 
    public uint zone; 
    public mBus bustype; 
    public mBus transporttype; 
    public cAddr i2cAddr;
    public mSpiCfg spiCfg; 
    public byte use_pmu; 
};

public enum retCode
{
    OK = 0,
    FAIL = -1,  
    BUS_ALREADY_LOADED = -2,
    BUS_TYPE_UNKNOWN = -3,
    BUS_LOAD_LIBRARY_FAIL = -4,
    BUS_GET_PROC_FAIL = -5,
    BUS_INIT_FAIL = -6,
    Err_CHIP_INIT = -7
};

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct mDrvIn
{
    public mInitCfg cfg;
};

[DllImport("mdrv.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
public static extern retCode cp_init(ref mDrvIn inp);

我用下面的代碼初始化

public static void init()
{
    mDrvIn di = new mDrvIn();
    retCode rc = new retCode();

    di.cfg.bustype = mBus.nI2C;
    di.cfg.init_bus_only = 1;
    di.cfg.transporttype = di.cfg.bustype;
    di.cfg.zone = 0x2 | 0x4000;

    rc = cp_init(ref di);
    if (rc < 0)
    {
        Console.Write("Failed to initialize. Error code: " + rc);
        return;
    }
}

問題是使用C ++初始化模塊可以正常工作,但是C#不能正常工作,它將始終返回錯誤代碼-5(這意味着總線錯誤:無法枚舉DLL中的總線函數),結構的指針似乎傳遞給了DLL成功無錯誤,因此我想知道我在C#中轉換的結構是否存在問題,因此傳遞給C ++函數的參數已損壞或有其他問題,有人可以幫助我嗎? 提前致謝。

在您的C ++代碼中,您將bool_t定義為一個unsigned char (8位),但是在您的C#代碼中,您使用了一個int (32位),因此您的結構在init_bus_only之后init_bus_only有效。

編輯:另外,在C ++代碼中,將init_bus_only設置為1,而在C#代碼中則沒有,但是您應該在沒有幫助的情況下找到它。 在詢問之前,請仔細檢查您的代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM