1

i'm trying to use a self written c lib to proces 2d array from python but with little success.

Here is my c code:

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

Now here is my python wrapper:

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)

And my python code where i use the function:

Test.py

import CamLibPy
from numpy import zeros

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

CamLibPy.TableCam(Anum)

print('Ended: ', Anum)

In this test program i try to change all the zeros in the array to ones. but as soon as i try to run this is get the following output:

Start: [[ 0. 0. 0.] [ 0. 0. 0.] [ 0. 0. 0.]]

x: 3 y: 3

Traceback (most recent call last): File "/media/pi/USB DISK/Test/Test.py", line 7, in CamLibPy.TableCam(Anum) File "/media/pi/USB DISK/Test/CamLibPy.py", line 21, in TableCam _CamLib.TableCam(ctypes.c_int(x), ctypes.c_int(y), array) ctypes.ArgumentError: argument 3: : expected LP_c_long instance instead of c_long_Array_3_Array_3

it's saying it expected a c_long but i clearly used c_int to make the arrayType

Can somebody tell me what i did wrong?

1 Answer 1

1
  • c_long is the same as c_int, but that is not the problem.

There are a number of issues:

  • The type of numpy.zeros is default float.
  • In the Python TableCam, A is never modified.
  • In the C TableCam, the 3rd parameter should be int* Array and the elements modified by computing i*y+j. That also agrees with argtypes, which was correct.
  • The numpy array can be coerced to the right ctypes type.

Corrected code (on Windows, for my testing):

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)

Output

Start:
[[0 0 0]
 [0 0 0]
 [0 0 0]]
Ended:
[[1 1 1]
 [1 1 1]
 [1 1 1]]
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks mate for the fast response. I tested the code om my raspberry and it works!! You have no idea how long i have been struggling with this code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.