I ran into a similar problem. Here is my code snippet that interfaces to the unmanaged libMPSSE.dll from C#. (If I knew how to upload a whole file, I could submit a full example program.) Enjoy!
// Derived from FT_DEVICE_LIST_INFO_NODE in ftd2xx.h
// With help from Microsoft's P/Invoke Interop Assistant
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet = System.Runtime.InteropServices.CharSet.Ansi)]
public struct FT_DEVICE_LIST_INFO_NODE
{
public uint Flags;
public uint Type;
public uint ID;
public uint LocId;
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 16)]
public string SerialNumber;
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 64)]
public string Description;
System.IntPtr ftHandle;
}
// Derived from ChannelConfig in libMPSSE_spi.h
// With help from Microsoft's P/Invoke Interop Assistant
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet = System.Runtime.InteropServices.CharSet.Ansi)]
public struct ChannelConfig
{
public uint ClockRate;
public byte LatencyTimer;
public uint configOptions;
public uint Pin;
public uint reserved;
}
[DllImport("libMPSSE.dll", CallingConvention = CallingConvention.Cdecl)]
static extern uint SPI_GetNumChannels(out uint numChannels);
[DllImport("libMPSSE.dll", CallingConvention = CallingConvention.Cdecl)]
static extern uint SPI_GetChannelInfo(uint index, out FT_DEVICE_LIST_INFO_NODE chanInfo);
[DllImport("libMPSSE.dll", CallingConvention = CallingConvention.Cdecl)]
static extern uint SPI_OpenChannel(uint index, out System.IntPtr handle);
[DllImport("libMPSSE.dll", CallingConvention = CallingConvention.Cdecl)]
static extern uint SPI_InitChannel(System.IntPtr handle, ref ChannelConfig config);
[DllImport("libMPSSE.dll", CallingConvention = CallingConvention.Cdecl)]
static extern uint SPI_CloseChannel(System.IntPtr handle);
[DllImport("libMPSSE.dll", CallingConvention = CallingConvention.Cdecl)]
static extern uint SPI_Read(System.IntPtr handle, [MarshalAs(UnmanagedType.LPArray)] byte[] buffer, uint sizeToTransfer, ref uint sizeTransfered, uint options);
[DllImport("libMPSSE.dll", CallingConvention = CallingConvention.Cdecl)]
static extern uint SPI_Write(System.IntPtr handle, [MarshalAs(UnmanagedType.LPArray)] byte[] buffer, uint sizeToTransfer, ref uint sizeTransfered, uint options);
[DllImport("libMPSSE.dll", CallingConvention = CallingConvention.Cdecl)]
static extern uint SPI_ReadWrite(System.IntPtr handle, [MarshalAs(UnmanagedType.LPArray)] byte[] inBuffer, [MarshalAs(UnmanagedType.LPArray)] byte[] outBuffer, uint sizeToTransfer, ref uint sizeTransfered, uint options);
[DllImport("libMPSSE.dll", CallingConvention = CallingConvention.Cdecl)]
static extern uint SPI_IsBusy(System.IntPtr handle, out Boolean state);
[DllImport("libMPSSE.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void Init_libMPSSE();
[DllImport("libMPSSE.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void Cleanup_libMPSSE();
[DllImport("libMPSSE.dll", CallingConvention = CallingConvention.Cdecl)]
static extern uint SPI_ChangeCS(System.IntPtr handle, ChannelConfig config);
[DllImport("libMPSSE.dll", CallingConvention = CallingConvention.Cdecl)]
static extern uint FT_WriteGPIO(System.IntPtr handle, byte dir, byte value);
[DllImport("libMPSSE.dll", CallingConvention = CallingConvention.Cdecl)]
static extern uint FT_ReadGPIO(System.IntPtr handle, out byte value);