我需要使用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 ++函数的参数已损坏或其他什么,任何人都可以帮助我吗?提前致谢。
答案 0 :(得分:0)
在C ++代码中,将bool_t
定义为unsigned char
(8位),但在C#代码中,使用int
(32位),因此结构停止在init_bus_only
之后有效。
编辑:此外,在您的C ++代码中,您将init_bus_only
设置为1,而在您的C#代码中则没有,但您应该在没有帮助的情况下找到它。在询问之前仔细检查您的代码。