1

出于学习目的,我想将一些 C 代码移植到 C#。我已经移植了一些代码,但是这个让我很头疼。如何将此代码转换为 C#?

typedef enum
{
    PXA_I2C_FAST_SPEED = 1,
    PXA_I2C_NORMAL_SPEED
} PXA_I2C_SPEED_T;

typedef enum
{
    I2C_OPCODE_READ             =   1,
    I2C_OPCODE_WRITE            =   2,
    I2C_OPCODE_READ_ONESTOP     =   3,
    I2C_OPCODE_WRITE_ONESTOP    =   4,
} PXA_I2C_OPERATION_CODE;

typedef struct
{
    /* input: */
    DWORD           mTransactions;
    PXA_I2C_SPEED_T mClkSpeed;
    UCHAR           mDeviceAddr;  //7 bit
    PXA_I2C_OPERATION_CODE          *mOpCode;
    DWORD           *mBufferOffset;
    DWORD           *mTransLen;
    /* output: */
    //DWORD         mErrorCode;
    UCHAR           *mBuffer;
} PXA_I2CTRANS_T;

然后某处稍后将结构 PXA_I2CTRANS_T 与 DeviceIoControl 一起使用,如下所示:

DeviceIoControl (hDevice, IOCTL_I2C_TRANSACT, NULL, 0, pTrans, sizeof(PXA_I2CTRANS_T), &BytesWritten, NULL);

我必须使用 IntPtr 吗?我是否必须将 ClockSpeed 转换为 DeviceAddress(因为 DeviceAddress 应该是 7 位,但在 C# 中它是 8 位)?为什么结构体像输出缓冲区一样使用,而它显然是要发送的东西(也有保留的内存来存储输出)?

我现在只有这个:

    [DllImport("coredll.dll", SetLastError = true)]
    private static extern bool DeviceIoControl(
        IntPtr hDevice,
        uint dwIoControlCode,
        IntPtr InBuffer,
        uint nInBufferSize,
        [In, Out] IntPtr OutBuffer,
        uint nOutBufferSize,
        IntPtr pBytesReturned,
        IntPtr lpOverlapped);

    public enum Speed
    {
        Fast = 1,
        Slow
    }

    public enum OperationCode
    {
        Read = 1,
        Write = 2,
        ReadOneStop = 3,
        WriteOneStop = 4
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct TransactionData
    {
        public uint Transactions;
        public I2cDevice.Speed ClockSpeed;
        public byte DeviceAddress;

        public IntPtr OpCode;
        public IntPtr BufferOffset;
        public IntPtr TransactionLength;

        public IntPtr Buffer;
    }

后来我将字节数组固定到结构并编组,所以我可以这样做:

TransactionData data = new TransactionData();

//declaring some arrays, allocating memory and pinning them to the struct
//also filling the non pointer fields with data

GCHandle handle1 = GCHandle.Alloc(data, GCHandleType.Pinned);
IntPtr p = handle1.AddrOfPinnedObject();
DeviceIoControl(Handle, CtrlCode.Transact, IntPtr.Zero, 0, p, (uint)Marshal.SizeOf(typeof(TransactionData)), bytesreturned, IntPtr.Zero);
4

0 回答 0