Hao
Hao

Reputation: 21

Importing C dll function to C#

this is my first stackoverflow post. I have been stucking in this issue for days. I try to import the usbi2cio.dll which is a C Dll to a C# based project. I went through most of the similar posts within the site, while still I couldn't fix my issue, since my case might be little different.

So here is the original definition of the API and related struct as a parameter:

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);

For some reason, the struct in the read I2C transaction can't be well passed through, As a result, the function returns 0 value without errors(what I expect is the same value with wCount). For some other similar API and struct, it works well. So what might be the cause for this issue?

//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); 

Upvotes: 2

Views: 718

Answers (1)

MadeInTheUSB
MadeInTheUSB

Reputation: 120

I had a similar problem, and I fixed it by writing my own C library called Bridge, that would deal with the complex C API but expose simple methods that could be interfaced with C# easily.

For example in the method below I could pass a byte array to my C code. From a C# point of view I would only deal with byte, int16 or int32 or byte array.

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

Upvotes: 1

Related Questions