Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

passing c++ double pointer to python

I could pass one-dimension array to python like below. and I wonder if I can pass c++ double pointer array to python by using ctypes, numpy.

test.cpp:

#include <stdio.h>
extern "C" void cfun(const void * indatav, int rowcount, int colcount, void * outdatav);

void cfun(const void * indatav, int rowcount, int colcount, void * outdatav) {
    //void cfun(const double * indata, int rowcount, int colcount, double * outdata) {
    const double * indata = (double *) indatav;
    double * outdata = (double *) outdatav;
    int i;
    puts("Here we go!");
    for (i = 0; i < rowcount * colcount; ++i) {
        outdata[i] = indata[i] * 4;
    }
    puts("Done!");
}

test.py:

import numpy
import ctypes

indata = numpy.ones((5,6), dtype=numpy.double)
outdata = numpy.zeros((5,6), dtype=numpy.double)
lib = ctypes.cdll.LoadLibrary('./ctest.so')
fun = lib.cfun
# Here comes the fool part.
#fun(ctypes.c_void_p(indata.ctypes.data), ctypes.c_void_p(outdata.ctypes.data))

fun(ctypes.c_void_p(indata.ctypes.data), ctypes.c_int(5), ctypes.c_int(6),
    ctypes.c_void_p(outdata.ctypes.data))


print 'indata: %s' % indata
print 'outdata: %s' % outdata
like image 668
wonjun Avatar asked Jan 09 '12 02:01

wonjun


1 Answers

Here's a way. I didn't see a nice way to use numpy with double**.

test.cpp (Windows)

#include <stdio.h>

extern "C" __declspec(dllexport) void cfun(const double ** indata, int rowcount, int colcount, double ** outdata) {
    for (int i = 0; i < rowcount; ++i) {
        for (int j = 0; j < colcount; ++j) {
            outdata[i][j] = indata[i][j] * 4;
        }
    }
}

test.py

import numpy
import ctypes

# Allocate array of double*
indata = (ctypes.POINTER(ctypes.c_double) * 5)()
for i in range(5):
    # Allocate arrays of double
    indata[i] = (ctypes.c_double * 6)()
    for j in range(6):
        indata[i][j] = 1.0

outdata = (ctypes.POINTER(ctypes.c_double) * 5)()
for i in range(5):
    outdata[i] = (ctypes.c_double * 6)()
    for j in range(6):
        outdata[i][j] = 1.0

lib = ctypes.cdll.LoadLibrary('test')
fun = lib.cfun

def dump(a,rows,cols):
    for i in range(rows):
        for j in range(cols):
            print a[i][j],
        print

dump(indata,5,6)
fun(ctypes.byref(indata),5,6,ctypes.byref(outdata))
dump(outdata,5,6)

Output

1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0
4.0 4.0 4.0 4.0 4.0 4.0
4.0 4.0 4.0 4.0 4.0 4.0
4.0 4.0 4.0 4.0 4.0 4.0
4.0 4.0 4.0 4.0 4.0 4.0
4.0 4.0 4.0 4.0 4.0 4.0
like image 59
Mark Tolonen Avatar answered Sep 16 '22 12:09

Mark Tolonen