SWIG - 将C字符串数组封装为Python列表

6 投票
3 回答
3599 浏览
提问于 2025-04-16 15:46

我在想,如何才能正确地把C语言中的字符串数组转换成Python的列表,使用SWIG这个工具。

这个数组是在一个结构体里面的:

typedef struct {
   char** my_array;
   char* some_string; 
}Foo;

SWIG会自动把some_string转换成Python字符串。

我在SWIG的接口文件里应该写些什么,才能让my_array在Python中像普通的字符串列表一样使用,比如 ['string1', 'string2'] 呢?

我按照建议使用了typemap:

%typemap(python,out) char** {
  int len,i;
  len = 0;
  while ($1[len]) len++;
  $result = PyList_New(len);
  for (i = 0; i < len; i++) {
    PyList_SetItem($result,i,PyString_FromString($1[i]));
  }
}

但是这样还是不行。在Python中,my_array这个变量显示为 SwigPyObject: _20afba0100000000_p_p_char。

我在想,这是不是因为char**在结构体里面?也许我需要告诉SWIG这一点?

有没有什么想法呢?

3 个回答

-1

抱歉我有点跑题,但如果你有这个选择,我强烈建议你使用ctypes,而不是swig。这里有一个我之前在ctypes相关内容中提问的问题:从python/ctypes传递字符串列表到期望char **的C函数

0

我不是这方面的专家,但我觉得:

%typemap(python,out) char** {

这个说的是一个返回 char ** 的函数。你的 char ** 在一个结构体里面……你可以看看 swig 生成的代码,确认一下映射是否应用成功。

你可能需要用类似下面的东西:

%typemap(python,out) struct Foo {

来处理一个返回的结构体 Foo 的映射。

背景:我用的和你一样的类型映射定义,但我成功地应用到了 char ** 上。

1

我觉得SWIG里没有自动处理这种转换的选项。你需要使用SWIG的Typemap功能,手动写一个类型转换器。在这里你可以找到一个把Python列表转换成char**的例子,链接是http://www.swig.org/Doc1.3/Python.html#Python_nn59,这就完成了一半的工作。接下来你需要做的就是查看Typemap的其他文档,写一个从char**转换到Python列表的转换器。

撰写回答