Marshalling struct containing an enum in C# -


brief : have got .dll function i'm trying use in c# application. 1 of function doesn't work , returns "invalid arguments" status.

i guessed marshalling issue.

here .dll header :

typedef unsigned char   uint8; typedef unsigned short  uint16; typedef unsigned long long uint64;  typedef signed char   int8; typedef signed short  int16; typedef signed long long int64;  #ifndef _msc_ver typedef unsigned char   bool; #endif  #ifdef __x86_64__       typedef unsigned int   uint32;     typedef signed int   int32; #else     typedef unsigned long   uint32;     typedef signed long   int32; #endif  typedef enum i2c_clockrate_t{     i2c_clock_standard_mode = 100000,                       /* 100kb/sec */     i2c_clock_fast_mode = 400000,                           /* 400kb/sec */     i2c_clock_fast_mode_plus = 1000000,                     /* 1000kb/sec */     i2c_clock_high_speed_mode = 3400000                     /* 3.4mb/sec */ }i2c_clockrate;   /* channel configuration information */ typedef struct channelconfig_t {     i2c_clockrate   clockrate;      uint8           latencytimer;     uint32          options; }channelconfig;  /******************************************************************************/  /******************************************************************************/ /*                              function declarations                         */ /******************************************************************************/ ftdi_api ft_status i2c_getnumchannels(uint32 *numchannels); ftdi_api ft_status i2c_getchannelinfo(uint32 index,      ft_device_list_info_node *chaninfo); ftdi_api ft_status i2c_openchannel(uint32 index, ft_handle *handle); ftdi_api ft_status i2c_initchannel(ft_handle handle, channelconfig *config); ftdi_api ft_status i2c_closechannel(ft_handle handle); ftdi_api ft_status i2c_deviceread(ft_handle handle, uint32 deviceaddress,  uint32 sizetotransfer, uint8 *buffer, uint32 *sizetransfered, uint32 options); ftdi_api ft_status i2c_devicewrite(ft_handle handle, uint32 deviceaddress,  uint32 sizetotransfer, uint8 *buffer, uint32 *sizetransfered, uint32 options); ftdi_api void init_libmpsse(void); ftdi_api void cleanup_libmpsse(void); ftdi_api ft_status ft_writegpio(ft_handle handle, uint8 dir, uint8 value); ftdi_api ft_status ft_readgpio(ft_handle handle,uint8 *value); 

so i've made c# wrapper use functions :

    #region declaration of general drivers methods      /// <summary>     /// function gets number of i2c channels connected host system. number of ports available in each of these chips different.     /// </summary>     /// <param name="numchannels">the number of channels connected host</param>     /// <returns>returns status code of type ft_status</returns>     [dllimport("libmpsse.dll", setlasterror = true, charset = charset.auto)]     public extern static ftdi.ft_status i2c_getnumchannels(             ref uint numchannels     );      /// <summary>     /// function takes channel index (valid values 0 value returned i2c_getnumchannels – 1 ) , provides information channel in form of populated ft_device_list_info_node structure     /// </summary>     /// <param name="index">index of channel </param>     /// <param name="chaninfo">pointer ft_device_list_info_node structure</param>     /// <returns>returns status code of type ft_status</returns>     [dllimport("libmpsse.dll", setlasterror = true, charset = charset.auto)]     public extern static ftdi.ft_status i2c_getchannelinfo(             uint index,             ref ftdi.ft_device_info_node chaninfo     );      /// <summary>     /// function opens indexed channel , provides handle it. valid values index of channel can 0 value obtained using i2c_getnumchannels – 1).     /// </summary>     /// <param name="index">index of channel</param>     /// <param name="handle">pointer handle of type ft_handle</param>     /// <returns>returns status code of type ft_status</returns>     [dllimport("libmpsse.dll", setlasterror = true, charset = charset.auto)]     public extern static ftdi.ft_status i2c_openchannel(             uint index,             ref ulong handle                     );      /// <summary>     /// function initializes channel , communication parameters associated it.     /// </summary>     /// <param name="handle">handle of channel </param>     /// <param name="config">pointer channelconfig structure. members of channelconfig structure contains values i2c master clock, latency timer , options</param>     /// <returns>returns status code of type ft_status</returns>     [dllimport("libmpsse.dll", setlasterror = true, charset = charset.auto)]     public extern static ftdi.ft_status i2c_initchannel(             ulong handle,             [marshalas(unmanagedtype.struct)] ref c_types.channelconfig config     );      /// <summary>     /// closes channel , frees resources used     /// </summary>     /// <param name="handle">handle of channel </param>     /// <returns>returns status code of type ft_status</returns>     [dllimport("libmpsse.dll", setlasterror = true, charset = charset.auto)]     public extern static ftdi.ft_status i2c_closechannel(             ulong handle     );      /// options summary     /// parameter specifies data transfer options. bit positions defined each of these options are:      /// bit0: if set start condition generated in i2c bus before transfer begins. bit mask defined options in file ftdi_i2c.h i2c_transfer_options_start_bit     /// bit1: if set stop condition generated in i2c bus after transfer ends. bit mask defined options in file ftdi_i2c.h i2c_transfer_options_stop_bit     /// bit2: reserved (only used in i2c_devicewrite)     /// bit3: i2c slaves require i2c master generate nak last data byte read. setting bit enables working such i2c slaves. bit mask defined bit i2c_transfer_options_nack_last_byte     /// bit4: setting bit invoke multi byte i2c transfer without having delays between start, address, data , stop phases. size of transfer in parameters sizetotransfer , sizetransfer red in bytes. bit mask defined bit i2c_transfer_options_fast_transfer_bytes*     /// bit5: setting bit invoke multi bit transfer without having delays between start, address, data , stop phases. size of transfer in parameters sizetotransfer , sizetransfer red in bytes. bit mask defined bit i2c_transfer_options_fast_transfer_bits*     /// bit6: deviceaddress parameter ignored if bit set. feature may useful in generating special i2c bus conditions not require address passed. setting bit effective when either 2c_transfer_options_fast_transfer_bytes or i2c_transfer_options_fast_transfer_bits set. bit mask defined bit i2c_transfer_options_no_address*     /// bit7–bit31:reserved     /// more information see an_177_user_guide_for_libmpsse-i2c.pdf      /// <summary>     /// function reads specified number of bytes addressed i2c slave     /// </summary>     /// <param name="handle">handle of channel </param>     /// <param name="deviceaddress">address of i2c slave. 7bit value , should not contain data direction bit, i.e. decimal value passed should less 128</param>     /// <param name="sizetotransfer">number of bytes read </param>     /// <param name="buffer">pointer buffer data read</param>     /// <param name="sizetransfered">pointer variable containing number of bytes read</param>     /// <param name="options">cf options</param>     /// <returns>returns status code of type ft_status</returns>     [dllimport("libmpsse.dll", setlasterror = true, charset = charset.auto)]     public extern static ftdi.ft_status i2c_deviceread(             ulong handle,             uint deviceaddress,             uint sizetotransfer,             ref byte buffer,             ref uint sizetransfered,             uint options     );      /// <summary>     /// function writes specified number of bytes addressed i2c slave.     /// </summary>     /// <param name="handle">handle of channel</param>     /// <param name="deviceaddress">address of i2c slave. 7bit value , should not contain data direction bit, i.e. decimal value passed should less 128</param>     /// <param name="sizetotransfer">number of bytes written</param>     /// <param name="buffer">pointer buffer data written</param>     /// <param name="sizetransfered">pointer variable containing number of bytes written</param>     /// <param name="options">cf options</param>     /// <returns></returns>     [dllimport("libmpsse.dll", setlasterror = true, charset = charset.auto)]     public extern static ftdi.ft_status i2c_devicewrite(             ulong handle,             uint deviceaddress,             uint sizetotransfer,             ref byte[] buffer,             ref uint sizetransfered,             uint options     );     #endregion 

i have managed use i2c_getnumchannels, i2c_openchannel , i2c_closechannel functions stucked on i2c_initchannel.

reminder :

.dll :

ftdi_api ft_status i2c_initchannel(ft_handle handle, channelconfig *config); 

wrapper :

[dllimport("libmpsse.dll", setlasterror = true, charset = charset.auto)]     public extern static ftdi.ft_status i2c_initchannel(             ulong handle,             [marshalas(unmanagedtype.struct)] ref c_types.channelconfig config     ); 

here c# structure implementation :

    /// <summary>     /// i2c clockrate enum pc i2c connection     /// </summary>     public enum i2c_clockrate     {         i2c_clock_standard_mode = 100000,                       /* 100kb/sec */         i2c_clock_fast_mode = 400000,                           /* 400kb/sec */         i2c_clock_fast_mode_plus = 1000000,                     /* 1000kb/sec */         i2c_clock_high_speed_mode = 3400000                     /* 3.4mb/sec */     };      /// <summary>     /// channel configuration information pc i2c connection     /// </summary>     [structlayout(layoutkind.sequential)]     public struct channelconfig     {         public i2c_clockrate clockrate;         public byte latencytimer;         public uint options;          public channelconfig(i2c_clockrate pclockrate, byte platencytimer, uint poptions)         {             clockrate = pclockrate;             latencytimer = platencytimer;             options = poptions;         }          public channelconfig(i2c_clockrate pclockrate, byte platencytimer)         {             clockrate = pclockrate;             latencytimer = platencytimer;             options = 0x00000000;         }     } 

the problem dll function return _ftstatus saying : "invalid arguments".

i'm guessing because did not marshalled function can't figure error be.


Comments

Popular posts from this blog

Fail to load namespace Spring Security http://www.springframework.org/security/tags -

sql - MySQL query optimization using coalesce -

unity3d - Unity local avoidance in user created world -