![](/img/trans.png)
[英]Marshalling "EGLRenderResolutionScaleProperty" to ANGLE from C# using P/Invoke
[英]Cannot p/invoke C method from C# due to marshalling issues
我正在嘗試調用下面的I2CTransfer
函數,並立即獲取System.NotSupportedException
。 我懷疑我的編組錯誤,但是無法解決問題。
這是C結構:
BOOL I2CTransfer(HANDLE hDev, PI2C_TRANSFER_BLOCK pI2CTransferBlock);
typedef struct {
I2C_PACKET *pI2CPackets;
INT32 iNumPackets;
} I2C_TRANSFER_BLOCK, *PI2C_TRANSFER_BLOCK;
typedef struct {
BYTE byAddr;
BYTE byRW;
PBYTE pbyBuf;
WORD wLen;
LPINT lpiResult;
} I2C_PACKET, *PI2C_PACKET;
這是我正在嘗試的c#結構:
[DllImport("i2csdk.dll", EntryPoint = "I2CTransfer")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool I2CTransfer(IntPtr hI2C,ref I2C_TRANSFER_BLOCK pI2CTransferBlock);
[StructLayout(LayoutKind.Sequential)]
public struct I2C_TRANSFER_BLOCK
{
public I2C_PACKET[] pI2CPackets;
public int iNumPackets;
}
[StructLayout(LayoutKind.Sequential)]
public struct I2C_PACKET
{
public byte byAddr;
public byte byRW;
public byte[] pbyBuf;
public UInt16 wLen;
public IntPtr lpiResult;
}
調用代碼:
I2C_TRANSFER_BLOCK i2CTransferBlock = new I2C_TRANSFER_BLOCK();
I2C_PACKET packet = new I2C_PACKET();
int result;
IntPtr resultPtr = IntPtr.Zero;
//Populating data...
byte[] pBuf = new byte[1 + pbData.Length];
pBuf[0] = (byte) ((regStart & 0x7F) << 1);
Array.Copy(pbData, 0, pBuf, 1, pbData.Length);
// Fill packet for register write
packet.pbyBuf = pBuf;
packet.wLen = (ushort) pBuf.Length;
packet.byRW = NativeConstants.I2C_RW_WRITE;
packet.byAddr = address;
packet.lpiResult = resultPtr;
// Fill transfer block
i2CTransferBlock.pI2CPackets = new I2C_PACKET[] {packet};
i2CTransferBlock.iNumPackets = 1;
// NotSupportedException here
bool brc = I2CTransfer(port, ref i2CTransferBlock);
在調用方法之前,使用C#初始化數組。
我嘗試添加[MarshalAs(UnmanagedType.LPArray)]
到陣列(pI2cPackets和pbyBuf)無濟於事。
這是在Windows CE緊湊框架.NET 3.5上。
上述翻譯有明顯的問題嗎?
提前謝謝了。
我絕不是Marshaling的專家,但我想我會提出一些想法以防萬一。
1)嘗試通過在代碼中為數組分配內存來手動封送數組(作為IntPtr
)。
2)此行IntPtr resultPtr = IntPtr.Zero;
看起來可疑。 通常,當您從托管代碼傳遞指向非托管代碼的指針時,您的工作就是為該指針分配(和釋放)內存。 簽出詳細信息http://msdn.microsoft.com/en-us/library/0szztey7%28v=VS.90%29.aspx
您的問題出在結構所包含的指針中:
[StructLayout(LayoutKind.Sequential)]
public struct I2C_TRANSFER_BLOCK
{
public I2C_PACKET[] pI2CPackets; // here ....
public int iNumPackets;
}
[StructLayout(LayoutKind.Sequential)]
public struct I2C_PACKET
{
public byte byAddr;
public byte byRW;
public byte[] pbyBuf; // .... and here
public UInt16 wLen;
public IntPtr lpiResult;
}
您不能說服p / invoke marshaller編組指向嵌入在結構內部的數組的指針。 這種編組形式僅適用於功能參數。
您需要將這兩個字段都聲明為IntPtr
並手動進行編組。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.