如何在Python中调用SWIG封装的带char const *[]参数的C函数mymain
解决Python调用SWIG封装的
mymain函数参数不匹配问题 因为SWIG默认对const char *[](等价于const char**)的类型映射没有自动适配Python列表,你可以用以下两种方法解决,不用修改原C代码:
方法一:修改SWIG接口文件添加类型映射
在你的SWIG接口(.i)文件中添加以下类型映射代码,让SWIG自动把Python列表转换成C端需要的const char*[]:
%typemap(in) const char *argv[] { if (!PyList_Check($input)) { PyErr_SetString(PyExc_TypeError, "参数必须是字符串列表"); return NULL; } int list_len = PyList_Size($input); // 分配内存,末尾加NULL终止符 $1 = (const char**)malloc((list_len + 1) * sizeof(char*)); for (int i = 0; i < list_len; i++) { PyObject *item = PyList_GetItem($input, i); if (!PyUnicode_Check(item)) { PyErr_SetString(PyExc_TypeError, "列表元素必须是字符串"); free($1); return NULL; } $1[i] = PyUnicode_AsUTF8(item); } $1[list_len] = NULL; } // 释放分配的内存,避免泄漏 %typemap(freearg) const char *argv[] { free($1); }
添加后重新用SWIG生成封装代码并编译,之后在Python里就能直接传空列表[]或字符串列表["test"]调用mymain了。
方法二:在Python中用ctypes构造符合要求的参数
如果不想修改SWIG接口,直接在Python代码里用ctypes构造char**类型的参数:
import ctypes import your_swig_module # 替换成你的SWIG生成的模块名 # 情况1:传空参数(函数实际忽略值,用这个最省事) argc = 0 # 构造一个长度为1的char*数组,末尾设为NULL argv = (ctypes.c_char_p * 1)() argv[0] = None your_swig_module.mymain(argc, argv) # 情况2:需要传测试字符串 argc = 1 argv = (ctypes.c_char_p * 2)() argv[0] = b"test" # 注意要传字节串 argv[1] = None your_swig_module.mymain(argc, argv)
因为你提到函数实际会忽略参数值,所以用第一种情况的空参数构造就足够满足需求。
内容的提问来源于stack exchange,提问作者jeremy_rutman
相关产品推荐
相关产品推荐

