2012-01-09 4 views
6

Je pourrais passer un tableau à une dimension à python comme ci-dessous. et je me demande si je peux passer tableau double pointeur c + + à python en utilisant ctypes, numpy.passant un double pointeur C++ vers python

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 
+0

c'est un hack que j'ai appris, mais pourquoi ne pas simplement passer les pointeurs comme des entiers longs? –

+0

parce que le type peut être double .. etc non seulement entier. – wonjun

+0

Les pointeurs peuvent toujours être représentés comme des entiers longs. puis renvoyé au type que vous voulez. –

Répondre

6

est ici un moyen. Je n'ai pas vu une bonne façon d'utiliser numpy avec 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) 

Sortie

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 
+0

J'ai eu une erreur lors de la création du fichier ".so" test.cpp: 4: 1: erreur: constructeur attendu, destructeur, ou conversion de type avant '(' token – wonjun

+0

Je suis sur Linux donc ce code ne fonctionne pas – wonjun

+0

ça marche bien sans "__declspec (dllexport)". merci et dans fortran, tableau multidimensionnel peut être passé directement avec numpy droite? fwrap .. en fait je cherche un tableau de passage parmi python <-> c, C++ <-> fortran – wonjun

Questions connexes