将C API中的复杂结构转换为Cython .pxd

时间:2019-05-01 09:56:18

标签: c header cython

我构建了一个python软件包,这将需要包装许多第三方C库。由于多种原因,我决定使用Cython。第一个供应商API很大,包含许多复杂的定义,到目前为止大多数还可以。我在供应商.h中遇到一个结构问题,该结构(从概念上来说)是这样的:

typedef struct {                                                                         
  unsigned int blah;
  union {
    struct {
      unsigned int a;
      unsigned char b;
      ...
    } s1;
    struct {
      unsigned int  a;   
      unsigned char b;
      ...
    } s2;
    struct {
      unsigned int  blah; 
      ...             
    } s3;
    struct {
      unsigned short blah
      ...
      union {
        struct {
          unsigned int a;
          unsigned int c;
          ...
        } tx;
        struct {
          unsigned int a;
          unsigned int c;
          ...
        } rx;
        unsigned char raw[24];
      } u1;
    } s5;
    ...
  } main_union;
} hw_params; 

typedef struct hw_config{
          ...
          hw_params         params;
          ...                   

        } HW_CONFIG;

typedef HW_CONFIG hwConfig;
typedef HW_CONFIG *phwConfig; 

typedef struct s_config {
          ...
          hwConfig hcfgs[...];
        } SYS_CONFIG;

typedef SYS_CONFIG XLdriverConfig;
typedef SYS_CONFIG *pXLdriverConfig;

我看到并提出了不同的建议,并获得了不同的成功。

  • 整理整个结构定义:由于变量名称相同(上面用a,b和c突出显示),我遇到了问题
  • cli分别对所有结构和联合进行cdef,然后组合它们:到目前为止,这是最好的方法,根据我在.pxy中的使用情况,在将值赋值后,我已经能够成功构建和测试结构的某些变量。由.c API函数设置。我尝试在外部部分cdef extern from r"bin\vendor.h":外部声明s1,s2等,仅在cdef extern from r"bin\vendor.h",中声明了SYS_CONFIG typedef,并且还尝试了在cdef extern from r"bin\vendor.h":中声明了所有定义。常见示例:enter image description here

我的问题是:对于这种情况,最好的方法是什么?不一定是在.pxd中提供确切定义的解决方案,但也可以是“用纯c语言编写到lib的接口,然后在pxd周围写(希望简化)”

这个问题可能可以删除,但是如果确实有帮助,我遇到的问题更多与.pyx的使用有关。图像和通常建议的方法最终对我有用,但要经过反复尝试。以下是将。pxd转换为完整的结构。

cdef extern from r"bin\vxlapi.h":

    cdef struct _canFD:
        unsigned int  arbitrationBitRate     # CAN bus timing for nominal / arbitration bit rate
        unsigned char sjwAbr
        unsigned char tseg1Abr
        unsigned char tseg2Abr
        unsigned char samAbr  # 1 or 3
        unsigned char outputMode
        unsigned char sjwDbr                 # CAN bus timing for data bit rate 
        unsigned char tseg1Dbr
        unsigned char tseg2Dbr
        unsigned int  dataBitRate
        unsigned char canOpMode

    cdef struct _most:
        unsigned int  activeSpeedGrade
        unsigned int  compatibleSpeedGrade
        unsigned int  inicFwVersion

    cdef struct _flexray:
        # status and cfg mode are part of xlFrGetChannelConfiguration, too 
        unsigned int  status                 # XL_FR_CHANNEL_CFG_STATUS_xxx 
        unsigned int  cfgMode                # XL_FR_CHANNEL_CFG_MODE_xxx 
        unsigned int  baudrate               # FlexRay baudrate in kBaud 

    cdef struct _ethernet:
        unsigned char macAddr[6] # MAC address (starting with MSB!)
        unsigned char connector  # XL_ETH_STATUS_CONNECTOR_xxx
        unsigned char phy        # XL_ETH_STATUS_PHY_xxx
        unsigned char link       # XL_ETH_STATUS_LINK_xxx
        unsigned char speed      # XL_ETH_STATUS_SPEED_xxx
        unsigned char clockMode  # XL_ETH_STATUS_CLOCK_xxx
        unsigned char bypass     # XL_ETH_BYPASS_xxx

    cdef struct _tx:
        unsigned int bitrate
        unsigned int parity
        unsigned int minGap

    cdef struct _rx:
        unsigned int bitrate
        unsigned int minBitrate
        unsigned int maxBitrate
        unsigned int parity
        unsigned int minGap
        unsigned int autoBaudrate

    cdef union _dir:
        _tx tx
        _rx rx
        unsigned char raw[24]


    cdef struct _a429:
        unsigned short channelDirection
        unsigned short res1
        _dir dir

    cdef struct _can:
        unsigned int bitRate
        unsigned char sjw
        unsigned char tseg1
        unsigned char tseg2
        unsigned char sam  # 1 or 3
        unsigned char outputMode
        unsigned char reserved[7]
        unsigned char canOpMode


    cdef union _data:
        _can can
        _canFD canfd
        _most most
        _flexray flexray
        _ethernet ethernet
        _a429 a429
        unsigned char raw[28]

    ctypedef struct XLbusParams:                                                                         
        unsigned int busType
        _data data

    ctypedef struct XL_CHANNEL_CONFIG:
        char                name [32]
        unsigned char       hwType                               # HWTYPE_xxxx (see above)
        unsigned char       hwIndex                              # Index of the hardware (same type) (0,1,...)
        unsigned char       hwChannel                            # Index of the channel (same hardware) (0,1,...)
        unsigned short      transceiverType                      # TRANSCEIVER_TYPE_xxxx (see above)
        unsigned short      transceiverState                     # transceiver state (XL_TRANSCEIVER_STATUS...)
        unsigned short      configError                          # XL_CHANNEL_CONFIG_ERROR_XXX (see above)
        unsigned char       channelIndex                         # Global channel index (0,1,...)
        unsigned long long  channelMask                          # Global channel mask (=1<<channelIndex)
        unsigned int        channelCapabilities                  # capabilities which are supported (e.g CHANNEL_FLAG_XXX)
        unsigned int        channelBusCapabilities               # what buses are supported and which are possible to be 
                                                                # activated (e.g. XXX_BUS_ACTIVE_CAP_CAN)

        # Channel          
        unsigned char       isOnBus                              # The channel is on bus
        unsigned int        connectedBusType                     # currently selected bus      
        XLbusParams         busParams
        unsigned int        _doNotUse                            # introduced for compatibility reasons since EM00056439

        unsigned int        driverVersion            
        unsigned int        interfaceVersion                     # version of interface with driver
        unsigned int        raw_data[10]

        unsigned int        serialNumber
        unsigned int        articleNumber

        char                transceiverName [32]  # name for CANcab or another transceiver

        unsigned int        specialCabFlags                      # XL_SPECIAL_CAB_XXX flags
        unsigned int        dominantTimeout                      # Dominant Timeout in us.
        unsigned char       dominantRecessiveDelay               # Delay in us.
        unsigned char       recessiveDominantDelay               # Delay in us.
        unsigned char       connectionInfo                       # XL_CONNECTION_INFO_XXX
        unsigned char       currentlyAvailableTimestamps         # XL_CURRENTLY_AVAILABLE_TIMESTAMP...
        unsigned short      minimalSupplyVoltage                 # Minimal Supply Voltage of the Cab/Piggy in 1/100 V
        unsigned short      maximalSupplyVoltage                 # Maximal Supply Voltage of the Cab/Piggy in 1/100 V
        unsigned int        maximalBaudrate                      # Maximal supported LIN baudrate
        unsigned char       fpgaCoreCapabilities                 # e.g.: XL_FPGA_CORE_TYPE_XXX
        unsigned char       specialDeviceStatus                  # e.g.: XL_SPECIAL_DEVICE_STAT_XXX
        unsigned short      channelBusActiveCapabilities         # like channelBusCapabilities (but without core dependencies)
        unsigned short      breakOffset                          # compensation for edge asymmetry in ns 
        unsigned short      delimiterOffset                      # compensation for edgdfde asymmetry in ns 
        unsigned int        reserved[3]

    ctypedef XL_CHANNEL_CONFIG  XLchannelConfig
    ctypedef XL_CHANNEL_CONFIG  *pXLchannelConfig

    ctypedef struct XL_DRIVER_CONFIG:
        unsigned int      dllVersion
        unsigned int      channelCount  # total number of channels
        unsigned int      reserved[10]
        XLchannelConfig   channel[64]   # [channelCount]

    ctypedef XL_DRIVER_CONFIG  XLdriverConfig
    ctypedef XL_DRIVER_CONFIG *pXLdriverConfig

.h

typedef struct {                                                                         
  unsigned int busType;
  union {
    struct {
      unsigned int bitRate;
      unsigned char sjw;
      unsigned char tseg1;
      unsigned char tseg2;
      unsigned char sam;  // 1 or 3
      unsigned char outputMode;
      unsigned char reserved[7];
      unsigned char canOpMode;
    } can;
    struct {
      unsigned int  arbitrationBitRate;     // CAN bus timing for nominal / arbitration bit rate
      unsigned char sjwAbr;
      unsigned char tseg1Abr;
      unsigned char tseg2Abr;
      unsigned char samAbr;  // 1 or 3
      unsigned char outputMode;
      unsigned char sjwDbr;                 // CAN bus timing for data bit rate 
      unsigned char tseg1Dbr;
      unsigned char tseg2Dbr;
      unsigned int  dataBitRate;
      unsigned char canOpMode;
    } canFD;
    struct {
      unsigned int  activeSpeedGrade;
      unsigned int  compatibleSpeedGrade;
      unsigned int  inicFwVersion;
    } most;
    struct {
      // status and cfg mode are part of xlFrGetChannelConfiguration, too 
      unsigned int  status;                 // XL_FR_CHANNEL_CFG_STATUS_xxx 
      unsigned int  cfgMode;                // XL_FR_CHANNEL_CFG_MODE_xxx 
      unsigned int  baudrate;               // FlexRay baudrate in kBaud 
    } flexray;
    struct {
      unsigned char macAddr[6]; // MAC address (starting with MSB!)
      unsigned char connector;  // XL_ETH_STATUS_CONNECTOR_xxx
      unsigned char phy;        // XL_ETH_STATUS_PHY_xxx
      unsigned char link;       // XL_ETH_STATUS_LINK_xxx
      unsigned char speed;      // XL_ETH_STATUS_SPEED_xxx
      unsigned char clockMode;  // XL_ETH_STATUS_CLOCK_xxx
      unsigned char bypass;     // XL_ETH_BYPASS_xxx
    } ethernet;
    struct {
      unsigned short channelDirection;
      unsigned short res1;
      union {
        struct {
          unsigned int bitrate;
          unsigned int parity;
          unsigned int minGap;
        } tx;
        struct {
          unsigned int bitrate;
          unsigned int minBitrate;
          unsigned int maxBitrate;
          unsigned int parity;
          unsigned int minGap;
          unsigned int autoBaudrate;
        } rx;
        unsigned char raw[24];
      } dir;
    } a429;
    unsigned char raw[28];
  } data;
} XLbusParams; 


// structures for xlGetDriverConfig
typedef struct s_xl_channel_config {
          char                name [XL_MAX_LENGTH + 1];
          unsigned char       hwType;                               //!< HWTYPE_xxxx (see above)
          unsigned char       hwIndex;                              //!< Index of the hardware (same type) (0,1,...)
          unsigned char       hwChannel;                            //!< Index of the channel (same hardware) (0,1,...)
          unsigned short      transceiverType;                      //!< TRANSCEIVER_TYPE_xxxx (see above)
          unsigned short      transceiverState;                     //!< transceiver state (XL_TRANSCEIVER_STATUS...)
          unsigned short      configError;                          //!< XL_CHANNEL_CONFIG_ERROR_XXX (see above)
          unsigned char       channelIndex;                         //!< Global channel index (0,1,...)
          XLuint64            channelMask;                          //!< Global channel mask (=1<<channelIndex)
          unsigned int        channelCapabilities;                  //!< capabilities which are supported (e.g CHANNEL_FLAG_XXX)
          unsigned int        channelBusCapabilities;               //!< what buses are supported and which are possible to be 
                                                                    //!< activated (e.g. XXX_BUS_ACTIVE_CAP_CAN)

          // Channel          
          unsigned char       isOnBus;                              //!< The channel is on bus
          unsigned int        connectedBusType;                     //!< currently selected bus      
          XLbusParams         busParams;
          unsigned int        _doNotUse;                            //!< introduced for compatibility reasons since EM00056439

          unsigned int        driverVersion;            
          unsigned int        interfaceVersion;                     //!< version of interface with driver
          unsigned int        raw_data[10];

          unsigned int        serialNumber;
          unsigned int        articleNumber;

          char                transceiverName [XL_MAX_LENGTH + 1];  //!< name for CANcab or another transceiver

          unsigned int        specialCabFlags;                      //!< XL_SPECIAL_CAB_XXX flags
          unsigned int        dominantTimeout;                      //!< Dominant Timeout in us.
          unsigned char       dominantRecessiveDelay;               //!< Delay in us.
          unsigned char       recessiveDominantDelay;               //!< Delay in us.
          unsigned char       connectionInfo;                       //!< XL_CONNECTION_INFO_XXX
          unsigned char       currentlyAvailableTimestamps;         //!< XL_CURRENTLY_AVAILABLE_TIMESTAMP...
          unsigned short      minimalSupplyVoltage;                 //!< Minimal Supply Voltage of the Cab/Piggy in 1/100 V
          unsigned short      maximalSupplyVoltage;                 //!< Maximal Supply Voltage of the Cab/Piggy in 1/100 V
          unsigned int        maximalBaudrate;                      //!< Maximal supported LIN baudrate
          unsigned char       fpgaCoreCapabilities;                 //!< e.g.: XL_FPGA_CORE_TYPE_XXX
          unsigned char       specialDeviceStatus;                  //!< e.g.: XL_SPECIAL_DEVICE_STAT_XXX
          unsigned short      channelBusActiveCapabilities;         //!< like channelBusCapabilities (but without core dependencies)
          unsigned short      breakOffset;                          //!< compensation for edge asymmetry in ns 
          unsigned short      delimiterOffset;                      //!< compensation for edgdfde asymmetry in ns 
          unsigned int        reserved[3];
        } XL_CHANNEL_CONFIG;

typedef XL_CHANNEL_CONFIG  XLchannelConfig;
typedef XL_CHANNEL_CONFIG  *pXLchannelConfig; 

typedef struct s_xl_driver_config {
          unsigned int      dllVersion;
          unsigned int      channelCount;  // total number of channels
          unsigned int      reserved[10];
          XLchannelConfig   channel[XL_CONFIG_MAX_CHANNELS];    // [channelCount]
        } XL_DRIVER_CONFIG;

typedef XL_DRIVER_CONFIG  XLdriverConfig;
typedef XL_DRIVER_CONFIG  *pXLdriverConfig;

0 个答案:

没有答案