мне нужно использовать C# для управления тестовым модуля с ++ DLL 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;
}
}
и я использую ниже структур C# при вызове функции DLL
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++, поврежден или что-то еще, может кто-нибудь мне поможет? заранее спасибо.
Проверьте 'Marshal.SizeOf()' ваших типов C# и сравните 'sizeof()' ваших типов C++. – flyx
printf ("size =>% d", di) это дает мне 256 Marshal.SizeOf (di) дает мне 32 , но не знаю, какая разница? моя структура C# по-прежнему неправильна даже после изменения int в байт для bool_t? – Allen
Нет разницы, 'sizeof' возвращает биты и' Marshal.SizeOf' байты, поэтому они одинаковы. – flyx