【问题标题】:How does SWIG wrap buffer(char array) and pointer from C to Python?SWIG 如何包装缓冲区(字符数组)和从 C 到 Python 的指针?
【发布时间】:2013-02-20 21:20:50
【问题描述】:

Swig 的手册让我有点困惑。我将我的 C 库包装到 python,以便我可以在 python 中测试我的 C 代码。现在我想知道如何在 Python 中访问 C 指针地址, 例如,这是我的代码

typedef struct _buffer_t {
char buf[1024];
char *next_ptr;
} buffer_t;



void parse_buffer(buffer_t * buf_p) {
    buf_p -> next_ptr ++;
}

我想要做的是下面,在 C 代码中

buffer_t my_buf;
my_buf.next_ptr = my_buf.buf;
parse_buffer(&my_buf);
expect_equal(&(my_buf.buf)+1, my_buf.next_ptr);

我如何在 Python 中做同样的事情? 导入 SWIG 包装模块后,我在 python 中有 buffer_t 类。

【问题讨论】:

    标签: python c swig


    【解决方案1】:

    问题在于 SWIG 试图将缓冲区包装为 Python 中的字符串,而不仅仅是一个指针。 next_ptr 的综合赋值将分配内存并制作字符串副本,而不仅仅是进行指针赋值。您可以通过多种方式解决此问题。

    最简单的就是在Python中使用%extend添加“reset buffer”方法:

    %extend {
      void resetPtr() {
        $self->next_ptr=$self->buf;
      }
    }
    

    然后可以在 Python 中调用它来进行你想要的分配。

    或者,如果您想强制将缓冲区视为另一个指针,您可以强制 SWIG 将两个成员都视为 void* 而不是 char*char[]。我曾希望每个类型都像 %apply 一样简单,但在我的测试中,memberin 和 memberout 似乎无法正常工作:

    %apply void * { char *next };
    %apply void * { char buf[ANY] };
    

    鉴于 memberin/memberout 类型映射对于完成这项工作至关重要,我认为 %extend 是迄今为止最干净的解决方案。

    【讨论】:

    • 感谢您指出 %extend 选项。它有效,我也用它来获取指针地址。
    • 一个后续问题,我有一个像 void my_func(void * ptr); 这样的函数如何将我的 buf_p->next_ptr 传递给它?我已经使用 %apply void * {char * next_ptr} 来替换类型。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多