出于学习目的,我想将一些 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);