2013-04-08 148 views
2

這是我的第一個stackoverflow帖子。我一直在這個問題上困擾數日。我嘗試將一個C DLL的usbi2cio.dll導入到一個基於C#的項目中。我瀏覽了網站中的大部分類似帖子,但仍然無法解決我的問題,因爲我的情況可能有點不同。將C dll函數導入C#

因此,這裏是API的原始定義及相關結構作爲參數:

LONG _stdcall DAPI_ReadI2c(HANDLE hDevInstance, I2C_TRANS * TransI2C); 
typedef struct _I2C_TRANS { 
    BYTE byTransType; 
    BYTE bySlvDevAddr; 
    WORD wMemoryAddr; 
    WORD wCount; 
    BYTE Data[256]; 
}I2C_TRANS, *PI2C_TRANS; 

//In my C# code, I did the translation like this: 
[StructLayoutAttribute(LayoutKind.Sequential), Serializable] 
public struct I2C_TRANS 
{ 
    public byte byTransType; 
    public byte bySlvDevAddr; 
    public ushort wMemoryAddr; 
    public ushort wCount; 
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 256, ArraySubType = UnmanagedType.I1)] 
    public byte[] Data; 

    public I2C_TRANS(int size) 
    { 
     Data = new byte[size]; 
     this.byTransType = 0x00; 
     this.bySlvDevAddr = 0x00; 
     this.wMemoryAddr = 0; 
     this.wCount = 0; 
    } 
}; 

public I2C_TRANS TransI2C = new I2C_TRANS(256); 
public IntPtr[] hDevice = new IntPtr[DAPI_MAX_DEVICES]; 
... 
TransI2C.byTransType = byTransType; 
TransI2C.bySlvDevAddr = bySlvDevAddr; 
TransI2C.wMemoryAddr = wMemoryAddr; 
TransI2C.wCount = wCount;// no larger than 64 
... 
if((hDevice[0] = DAPI_OpenDeviceInstance(devName, 0)) != INVALID_HANDLE_VALUE) 
    //the returned lReadCnt should be equal to wCount. 
    Public int lReadCnt = DAPI_ReadI2c(hDevice[0], ref TransI2C); 

出於某種原因,在讀I2C交易結構不能很好地通過,其結果是,該函數返回0值沒有錯誤(我期望與wCount相同的值)。對於其他類似的API和結構,它運行良好。那麼這個問題可能是什麼原因呢?

//Here is the P/Invoke declaration: 
[DllImportAttribute("UsbI2cIo.dll", EntryPoint = "DAPI_ReadI2c", CallingConvention = CallingConvention.StdCall)] 
public static extern int DAPI_ReadI2c(IntPtr hDevInstance, ref I2C_TRANS TransI2C); 
+2

什麼是P/Invoke聲明?另外,試着讓C#結構變成一個類而不是一個結構,並從P/Invoke中移除'ref'。 – 2013-04-08 18:45:16

+0

pinvoke上的聖經是亞當Nathans - .NET和COM:完整的互操作性指南 – pm100 2013-04-08 18:59:54

+0

棘手的是另一個API是:「[DllImportAttribute(」UsbI2cIo.dll「,EntryPoint =」DAPI_GetDeviceInfo「,CallingConvention = CallingConvention.StdCall) ] public static extern byte DAPI_GetDeviceInfo([MarshalAsAttribute(UnmanagedType.LPStr)] StringBuilder lpsDevName,ref LPDEVINFO lpDevInfo);「它具有類似的結構格式和傳遞參數,但讀/寫部分運行緩慢。 – Hao 2013-04-08 19:03:36

回答

1

我也有類似的問題,我寫我自己的C庫調用橋,將處理複雜的C API,但暴露,可以用C#很容易地對接的簡單方法固定它。

例如在下面的方法中,我可以將一個字節數組傳遞給我的C代碼。 從C#的角度來看,我只會處理byte,int16或int32或byte數組。

[DllImport(DLL)] 
private static extern System.Int32 __SPI_Helper_Write(IntPtr lpBuffer, System.Int32 len);