0

Hello I am trying to write a simple C function that takes two inputs (m,n) and creates a 2D - array of pointers. Now I want to call that function in Ctypes and create a numpy array from the pointers. I am however not sure how to proceed - and run into an error when calling the np.frombuffer - function. Any help is apprechiated

c- file

#include <stdio.h>
#include <stdlib.h>

#define RANDOM_RANGE 50

typedef struct {
    float val;
} cell;

cell **matrixMake(int m, int n){

    // the rows
    cell **pRow = (cell **)malloc(m* sizeof(cell *));
    // the cols
    for (int i = 0; i < m; i++){
        pRow[i] = (cell *)malloc(n * sizeof(cell));
    }

    for (int i = 0; i < m; i++){
        for (int j = 0; j < n; j++){
            pRow[i][j].val = (float) (rand() % RANDOM_RANGE);
        }
    }

    return pRow;
}

Corresponding Python File

import numpy as np
from numpy.ctypeslib import ndpointer
from ctypes import *



class CELL(Structure):
    _fields_ = [ ('val', c_float) ]

libc = CDLL("c_arr_multi.so")

libc.matrixMake.argtypes = [ c_int, c_int ]
libc.matrixMake.restype = POINTER(POINTER(CELL))
res = libc.matrixMake(6, 3)

x = np.frombuffer((c_float * 6 * 3).from_address(libc.matrixMake(6, 3)), np.float32).copy()

print(x)

I am simply not shure how to proceed

baconStrips
  • 101
  • 9
  • I only have a passing knowledge of `C`, but it looks like you've defined a 2d array by starting with an array of pointers, each which is itself an array (of pointers or values). That structure is more like a Python nested list. `numpy` has one `C` databuffer with all values (not pointers), and `shape` (and `strides`) tuples that control how its methods iterate through those values. – hpaulj Mar 26 '21 at 01:42
  • Thanks for the answer. Hmm would you simply loop through the nested array and populate a numpy array then? I am also just a beginner, but that seems somewhat inefficient to me. – baconStrips Mar 26 '21 at 02:10
  • Maybe Python expects a 2D array? A pointer table isn't a 2D array, it is a method of emulating a 2D array for the sole purpose of making your program needlessly slow. See [Correctly allocating multi-dimensional arrays](https://stackoverflow.com/q/42094465/584518). – Lundin Mar 26 '21 at 08:54
  • 1
    @baconStrips It's in fact more efficient to have a single contiguous buffer than a buffer of pointers in which each pointer points to other buffers scattered though memory. – Mark Tolonen Mar 26 '21 at 17:43
  • https://stackoverflow.com/questions/58226790/c-python-pass-and-return-a-2d-double-pointer-array-from-python-to-c/58262388#58262388, https://stackoverflow.com/questions/58727931/how-to-pass-a-2d-array-from-python-to-c, https://stackoverflow.com/questions/58781199/how-can-i-cast-a-double-pointer-ctype-to-numpy-array/58784385#58784385, https://stackoverflow.com/questions/57295045/problems-with-passing-and-getting-arrays-for-a-c-function-using-ctypes/57299823#57299823. – CristiFati Mar 26 '21 at 18:00

0 Answers0