繁体   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