如何在Python上将列表传递给ctypes函数

时间:2018-07-02 07:55:21

标签: c python-2.7 ctypes

这是一个分为两部分的问题。为了提供一些背景知识,我有一个C代码,如下所示:

int c_func(const char* dir, float a, float b, float c, float d )
{
    printf("%s\n", dir);
    printf("%f\n",a);
    printf("%f\n",b);
    printf("%f\n",c);
    printf("%f\n",d);

    return 0;
}

这是一个简单的函数,它接受一个字符串,并以4个浮点数作为参数并将其打印输出,我正在尝试测试phython / C接口。我的python代码如下:

calling_function = ctypes.CDLL("/home/ruven/Documents/Sonar/C interface/Interface.so")  
calling_function.c_func("hello",1, 2, 3, 4])

现在,由于此方法有效,因此我不想传递4个单独的浮点数,而是要传递4个浮点数的列表。我已经在网上尝试了不同的代码来编辑C函数,以便将一个列表作为其参数之一,但是由于我是一名新程序员,并且对C并不熟悉,因此我似乎无法弄清楚该怎么做。 >

问题1:如何编写C函数以接受列表作为其参数?

问题2:这四个浮点数的列表实际上来自我的python代码的列表。在对C函数进行编码之后,我可以使用名为testfv2[0,:]的numpy数组作为C函数的输入吗?testfv2[0,:]是尺寸为1x4的列表,而testfv2是尺寸为列表的117x4。现在,我想一次进入C函数1行,这就是为什么我认为使用testfv2[0,:]

1 个答案:

答案 0 :(得分:1)

  

如何编写C函数以接受列表作为其参数?

简短回答,您不能

长答案:C没有列表,但是有数组和指针。

那么您有几种选择:

int c_func(const char *dir, float abcd[4]) { // using an array with explicit size

int c_func(const char *dir, float abcd[]) { // Using an array (will decay to a pointer at compile-time)

int c_func(const char *dir, float *abcd) { // Using a pointer.

如果您只会收到4个浮点数,我建议您采用第一种形式,该形式会强制增大数组的大小,函数的任何用户(主要是您将来的自己)都将知道仅给出四个元素的数组

从Python调用函数:

floats = [1.0, 2.0, 3.0, 4.0] # Or whatever values you want to pass, but be sure to give only 4
FloatArray4 = ctypes.c_float * 4 # Define a 4-length array of floats
parameter_array = FloatArray4(*floats) # Define the actual array to pass to your C function

我不知道向FloatArray4传递超过4个浮点数是否会引发错误-我猜是这样,但是我现在无法检查。

关于第二个问题,如果您想要动态大小的数组(超过4个元素),则必须为C函数选择另外两个配置文件之一,在这种情况下,我建议您添加一个额外的{ {1}}参数,用于数组的大小:

int

int c_func(const char *dir, float floats[], int size) {

您也可以使用标准的size_t代替int c_func(const char *dir, float *floats, int size) { ,它是专门为此设计的。

我要传递多维数组,请添加另一对括号:

int

但请记住,对于C数组,除第一个维度外的所有维度,都必须明确指定维度。如果该值是常数,则不会有问题,但是如果不是,则必须使用指针:

int c_func(const char *dir, float floats[][4]) { // Note the explicit size for second dimension

int c_func(const char *dir, float *floats[]) {

是两种相同的语法(数组将衰减为指针)。再说一次,如果您的尺寸是动态的,我建议添加尺寸参数。

如果要补充尺寸,只需重复最后一步。