Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将字符串列表从python/ctypes传递到C函数**_Python_C_Ctypes - Fatal编程技术网

将字符串列表从python/ctypes传递到C函数**

将字符串列表从python/ctypes传递到C函数**,python,c,ctypes,Python,C,Ctypes,我有一个C函数,它需要一个以列表\0结尾的字符串作为输入: void external_C( int length , const char ** string_list) { // Inspect the content of string_list - but not modify it. } 从python(使用ctypes)中,我想基于python字符串列表调用此函数: def call_c( string_list ): lib.external_C( ?? )

我有一个C函数,它需要一个以列表\0结尾的字符串作为输入:

void external_C( int length , const char ** string_list) { 
   // Inspect the content of string_list - but not modify it.
} 
从python(使用ctypes)中,我想基于python字符串列表调用此函数:

def call_c( string_list ):
    lib.external_C( ?? )

call_c( ["String1" , "String2" , "The last string"])
有关于如何在python端构建数据结构的提示吗?注意,我保证C函数不会改变string_列表中字符串的内容

问候


约金

非常感谢你;这很有魅力。我还做了一个类似这样的替代变化:

def call_c( L ):
    arr = (ctypes.c_char_p * (len(L) + 1))()
    arr[:-1] = L
    arr[ len(L) ] = None
    lib.external_C( arr )

然后在C函数中,我迭代了(char**)列表,直到找到一个空值。

我只是使用SWIG typemap创建它

1.在
demo.i
接口文件中编写自定义类型映射

%module demo

/* tell SWIG to treat char ** as a list of strings */
%typemap(in) char ** {
    // check if is a list
    if(PyList_Check($input))
    {
        int size = PyList_Size($input);
        int i = 0;
        $1 = (char **)malloc((size + 1)*sizeof(char *));
        for(i = 0; i < size; i++)
        {
            PyObject * o = PyList_GetItem($input, i);
            if(PyString_Check(o))
                $1[i] = PyString_AsString(o);
            else
            {
                PyErr_SetString(PyExc_TypeError, "list must contain strings");
                free($1);
                return NULL;
            }
        }
    }
    else
    {
        PyErr_SetString(PyExc_TypeError, "not a list");
        return NULL;
    }
}

// clean up the char ** array
%typemap(freearg) char ** {
    free((char *) $1);
}
3.导入python中的模块

>>> from demo import yourfunction
使用ctypes 创建到期日列表(字符串) 发送字符串数组的逻辑 通过在数组中循环,将字符串数组转换为字节数组 用于启动长度为数组的指针的逻辑类型 将字节数组赋给指针
C函数如何知道它已到达
const char*
序列的末尾;一般来说,它当然不知道。我的意图是用NULL终止它,或者我可以传递长度和(char**)指针-我可以完全控制所讨论的C库。若阿基米夫,它不知道,那很没用。你需要以某种方式告诉它,然后告诉我们,这样我们才能给你有效的代码;我不认为那有那么重要。无论如何,我现在已经更改了C函数的定义,因此它将一个长度参数作为第一个参数。对不起,外部C的argtypes应该是什么?请注意,在Python 3.x中,字符串默认为unicode,因此您应该通过
s.encode('utf-8')
bytes(s,'utf-8')
(或者任何你想使用的不是UTF-8的编码)。最好把这个^合并到答案中
$ swig -python demo.i  // generate wrap code
$ gcc -c -fpic demo.c demo_wrap.c
$ gcc -shared demo.o demo_wrap.o -o _demo.so
>>> from demo import yourfunction
expiries = ["1M", "2M", "3M", "6M","9M", "1Y", "2Y", "3Y","4Y", "5Y", "6Y", "7Y","8Y", "9Y", "10Y", "11Y","12Y", "15Y", "20Y", "25Y", "30Y"]
 expiries_bytes = []
    for i in range(len(expiries)):
        expiries_bytes.append(bytes(expiries[i], 'utf-8'))
expiries_array = (ctypes.c_char_p * (len(expiries_bytes)+1))()
expiries_array[:-1] = expiries_bytes