首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CFFI -使用结构与#ifdef

CFFI -使用结构与#ifdef
EN

Stack Overflow用户
提问于 2018-09-05 08:23:09
回答 1查看 1.5K关注 0票数 1

目前,我正在将一些现有的C-代码包装到Python中。它在CFFI上运行得很好,但我最后一件事还不明白。

如何处理"#ifdef“语句?

假设我在c中有这个结构:

代码语言:javascript
复制
typedef struct can_config_tag
{
    char_t type[4];
    uint16_t module_nr;
#ifdef CAN_MON
    uint16_t rx_main_mon;
#endif
    byte_t rx_obj;
}

我不明白如何包装这些"#ifdef“语句。在文档中,我发现了一些与“.”有关的内容,但是如何访问结构的数据呢?

当试图使用..。并以下列方式访问这些数据:

代码语言:javascript
复制
can_config= ffi.new("can_config_tag *")
can_config.rx_main_mon = 2

我说错了:

代码语言:javascript
复制
AttributeError: cdata 'struct can_config_tag*' has no field 'rx_main_mon'

那么,在使用cffi时,如何处理这些预处理指令,有什么解决办法吗?提前谢谢。

EN

回答 1

Stack Overflow用户

发布于 2018-09-05 10:09:59

问题是,ffi.cdef()不能给出依赖于预处理指令的结果,因为这些指令在调用C编译器时才会知道。(这可能会在非在线构建的情况下得到解决,但并不是即时的。)

有两种可能的解决办法:

  1. 执行几个编译步骤。
  2. 不要公开可选字段,而是添加自定义访问器函数。

对于1.,写这样的东西:

代码语言:javascript
复制
ffi_pre = FFI()
ffi_pre.cdef("#define CAN_MON_IS_DEFINED ...")
ffi_pre.set_source("_tmp_cffi", """
    #include <foo_mon.h>
    #ifdef CAN_MON
    #  define CAN_MON_IS_DEFINED 1
    #else
    #  define CAN_MON_IS_DEFINED 0
    #endif
""")
ffi_pre.compile()
from _tmp_cffi import ffi as ffi_tmp
can_mon = ffi_tmp.CAN_MON_IS_DEFINED

...then像您已经编写的代码一样编写其余的代码,但是在某个地方使用if can_mon:作为Python代码,例如在cdef中构建字符串:

代码语言:javascript
复制
"""
typedef struct can_config_tag
{
    char_t type[4];
    uint16_t module_nr;
""" + ("uint16_t rx_main_mon;" if can_mon else "") + """
    byte_t rx_obj;
};
"""

解决方案2是永远不要定义字段rx_main_mon,而是在定义字段时添加读取和写入字段的C函数:

代码语言:javascript
复制
ffi.cdef("""
typedef struct can_config_tag
{
    char_t type[4];
    uint16_t module_nr;
    byte_t rx_obj;
};
int my_read_rx_main_mon(struct can_config_tag *);
void my_write_rx_main_mon(struct can_config_tag *, int value);
""")
ffi.set_source("somename", """
#include <foomon.h>
static int my_read_rx_main_mon(struct can_config_tag *p)
{
#ifdef CAN_MON
    return p->rx_main_mon;
#else
    return -1;
#endif
}
static void my_write_rx_main_mon(struct can_config_tag *p, int value)
{
#ifdef CAN_MON
    p->rx_main_mon = value;
#endif
}
""")
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52180467

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档