【问题标题】:Python 2D array i C using ctypesPython 2D 数组 i C 使用 ctypes
【发布时间】:2017-08-26 04:02:47
【问题描述】:

我正在尝试使用自写的 c 库从 python 处理二维数组,但收效甚微。

这是我的 c 代码:

CamLibC.c

int TableCam(const int x, const int y, int **Array) {
    int i = 0;
    int j = 0;

    for (i; i < x; i++) {
        for (j; j < y; j++) {
            Array[i][j] = 1;
        };

    };
}

cc -nostartfiles -shared -fPIC -o CamLibOS.os CamLibC.c

现在这是我的 python 包装器:

CamLibPy.py

import os,sys
import ctypes

dirname     = os.path.dirname(os.path.realpath(sys.argv[0]))
CamLibFile  = dirname + '/CamLibOS.os'

_CamLib = ctypes.CDLL(CamLibFile)
_CamLib.TableCam.argtypes = [ctypes.c_int, ctypes.c_int, ctypes.POINTER(ctypes.c_int)]

def TableCam (A) :
    global _CamLib

    x = len(A)
    y = len(A[0])

    print('x: ', x, ' y: ', y);

    arrayType = ((ctypes.c_int * x) * y)
    array = arrayType()

    _CamLib.TableCam(ctypes.c_int(x), ctypes.c_int(y), array)

    print(array)

以及我使用该函数的python代码:

Test.py

import CamLibPy
from numpy import zeros

Anum = zeros((3,3))
print('Start: ', Anum)

CamLibPy.TableCam(Anum)

print('Ended: ', Anum)

在这个测试程序中,我尝试将数组中的所有零更改为一。但是一旦我尝试运行,就会得到以下输出:

开始:[[ 0. 0. 0.] [ 0. 0. 0.] [ 0. 0. 0.]]

x: 3 y: 3

Traceback(最近一次调用最后一次):文件“/media/pi/USB DISK/Test/Test.py”,第 7 行,在 CamLibPy.TableCam(Anum) 文件“/media/pi/USB DISK/Test/CamLibPy.py”,第 21 行,在 TableCam _CamLib.TableCam(ctypes.c_int(x),ctypes.c_int(y),数组)ctypes.ArgumentError:参数3::预期 LP_c_long 实例而不是 c_long_Array_3_Array_3

它是说它需要一个 c_long 但我显然使用 c_int 来制作 arrayType

谁能告诉我我做错了什么?

【问题讨论】:

    标签: python c arrays testing ctypes


    【解决方案1】:
    • c_longc_int 相同,但这不是问题。

    有很多问题:

    • numpy.zeros 的类型是默认浮点数。
    • 在 Python TableCam 中,A 永远不会被修改。
    • 在CTableCam中,第三个参数应该是int* Array,计算修改的元素i*y+j。这也与argtypes 一致,这是正确的。
    • numpy 数组可以强制转换为ctypes 类型。

    更正的代码(在 Windows 上,用于我的测试):

    cam.c

    #include <stdio.h>
    __declspec(dllexport) void TableCam(const int x, const int y, int *Array)
    {
        int i,j;
        for (i = 0; i < x; i++)
            for (j = 0; j < y; j++)
                Array[i*y+j] = 1;
    }
    

    camlib.py

    import ctypes
    
    _CamLib = ctypes.CDLL('cam')
    _CamLib.argtypes = [ctypes.c_int, ctypes.c_int, ctypes.POINTER(ctypes.c_int)]
    _CamLib.restype = None
    
    def TableCam(A):
        x,y = A.shape
        array = A.ctypes.data_as(ctypes.POINTER(ctypes.c_int))
        _CamLib.TableCam(x,y,array)
    

    test.py

    import camlib
    import numpy as np
    
    Anum = np.zeros((3,3),dtype=np.int)
    print('Start:')
    print(Anum)
    camlib.TableCam(Anum)
    print('Ended:')
    print(Anum)
    

    输出

    Start:
    [[0 0 0]
     [0 0 0]
     [0 0 0]]
    Ended:
    [[1 1 1]
     [1 1 1]
     [1 1 1]]
    

    【讨论】:

    • 感谢伙伴的快速响应。我用我的覆盆子测试了代码,它可以工作!!你不知道我为这段代码苦苦挣扎了多久。
    猜你喜欢
    • 2014-04-20
    • 1970-01-01
    • 1970-01-01
    • 2013-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多