我构建了一个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;
我看到并提出了不同的建议,并获得了不同的成功。
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":
中声明了所有定义。常见示例:
我的问题是:对于这种情况,最好的方法是什么?不一定是在.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;