2013-04-08 94 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);