[英]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.