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