【问题标题】:Passing an array using Ctypes使用 Ctypes 传递数组
【发布时间】:2013-12-27 18:45:36
【问题描述】:

所以我的python程序是

from ctypes import *
import ctypes

number = [0,1,2]
testlib = cdll.LoadLibrary("./a.out")


testlib.init.argtypes = [ctypes.c_int]
testlib.init.restype = ctypes.c_double

#create an array of size 3
testlib.init(3)

#Loop to fill the array

#use AccessArray to preform an action on the array

而C部分是

#include <stdio.h>


double init(int size){
    double points[size];

    return points[0];
}

double fillarray(double value, double location){

    // i need to access 
}

double AccessArray(double value, double location){

    // i need to acess the array that is filled in the previous function
}

所以我需要做的是将一个数组从 python 部分传递给 C 函数,以某种方式将该数组在 C 中移动到另一个函数,我将在其中访问它以便处理它。

我被困住了,因为我想不出一种方法来移动 C 部分中的数组。

谁能教我怎么做?

【问题讨论】:

    标签: python arrays ctypes


    【解决方案1】:

    你应该尝试这样的事情(在你的 C 代码中):

    #include <stdio.h>
    
    double points[1000];//change 1000 for the maximum size for you
    int sz = 0;
    
    double init(int size){
        //verify size <= maximum size for the array
        for(int i=0;i<size;i++) {
            points[i] = 1;//change 1 for the init value for you
        }
        sz = size;
        return points[0];
    }
    
    double fillarray(double value, double location){
        //first verify 0 < location < sz
        points[(int)location] = value;    
    }
    
    double AccessArray(double value, double location){
        //first verify 0 < location < sz
        return points[(int)location];
    }
    

    这是一个非常简单的解决方案,但是如果您需要分配一个任意大小的数组,您应该研究使用malloc

    【讨论】:

    • 这看起来不错,只是你提到了 malloc,我看了看,但我不知道如何使用它来创建给定大小的数组。
    • points = malloc(size * sizeof(double)); 就像在 dstromberg 的回答中一样
    【解决方案2】:

    也许是这样的?

    $ cat Makefile
    
    go: a.out
            ./c-double
    
    a.out: c.c
            gcc -fpic -shared c.c -o a.out
    
    zareason-dstromberg:~/src/outside-questions/c-double x86_64-pc-linux-gnu 27062 - above cmd done 2013 Fri Dec 27 11:03 AM
    
    $ cat c.c
    #include <stdio.h>
    #include <malloc.h>
    
    
    double *init(int size) {
        double *points;
    
        points = malloc(size * sizeof(double));
    
        return points;
    }
    
    double fill_array(double *points, int size) {
        int i;
        for (i=0; i < size; i++) {
            points[i] = (double) i;
        }
    
    }
    
    double access_array(double *points, int size) {
        // i need to access the array that is filled in the previous function
        int i;
        for (i=0; i < size; i++) {
            printf("%d: %f\n", i, points[i]);
        }
    }
    zareason-dstromberg:~/src/outside-questions/c-double x86_64-pc-linux-gnu 27062 - above cmd done 2013 Fri Dec 27 11:03 AM
    
    $ cat c-double
    #!/usr/local/cpython-3.3/bin/python
    
    import ctypes
    
    testlib = ctypes.cdll.LoadLibrary("./a.out")
    
    testlib.init.argtypes = [ctypes.c_int]
    testlib.init.restype = ctypes.c_void_p
    
    #create an array of size 3
    size = 3
    double_array = testlib.init(size)
    
    #Loop to fill the array
    testlib.fill_array(double_array, size)
    
    #use AccessArray to preform an action on the array
    testlib.access_array(double_array, size)
    

    【讨论】:

    • 我尝试了你的代码,但我一直遇到分段错误,似乎与填充和访问数组部分有关。
    • 设置init.restype = POINTER(c_double),但如果可以避免的话,这确实是一个尴尬的设计。让客户端分配数组:init.argtypes = [c_int, POINTER(c_double)]; double_array = (c_double * size)(); init(size, double_array)。现在double_array 由 Python 管理,引用计数对象。您不必担心mallocfree。 Python 会为您做到这一点。
    • 我尝试将 testlib.init.restype = ctypes.c_void_p 更改为 testlib.init.restype = POINTER(c_double) 但现在我在 testlib 中得到文件“test.py”,第 7 行.init.restype = POINTER(c_double) NameError: name 'POINTER' is not defined
    • @JohnTracey:我只是不想重复输入ctypes。在任何变老的专业中。在一个模块中输入ctypes 几百次。
    • 哦,哎呀忘了添加:P,现在可以使用了,感谢您的帮助。
    猜你喜欢
    • 2014-12-04
    • 2019-08-04
    • 1970-01-01
    • 2014-04-20
    • 2017-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-13
    相关资源
    最近更新 更多