2012-01-09 2 views
6

पर सी ++ डबल पॉइंटर पास करने से मैं नीचे की तरह पायथन के लिए एक-आयाम सरणी पारित कर सकता हूं। और मुझे आश्चर्य है कि क्या मैं cty+, numpy का उपयोग कर पाइथन में C++ डबल पॉइंटर सरणी पास कर सकता हूं।पाइथन

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

यह एक हैक मैं सिखाया गया है है, लेकिन क्यों सिर्फ संकेत पारित नहीं लंबे पूर्णांक के रूप में? –

+0

क्योंकि टाइप डबल हो सकता है .. आदि न केवल पूर्णांक। – wonjun

+0

पॉइंटर्स को हमेशा लंबे पूर्णांक के रूप में प्रदर्शित किया जा सकता है। और उसके बाद आप जो कुछ भी चाहते हैं उसे वापस डालें। –

उत्तर

6

यहाँ एक तरीका है। मुझे डबल ** के साथ numpy का उपयोग करने का एक अच्छा तरीका नहीं देखा।

test.cpp (विंडोज़)

#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) 

आउटपुट

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

मुझे ".so" फ़ाइल बनाते समय एक त्रुटि मिली test.cpp: 4: 1: त्रुटि: अपेक्षित कन्स्ट्रक्टर, विनाशक, या टाइप रूपांतरण से पहले '(' टोकन – wonjun

+0

मैं लिनक्स पर हूं इसलिए यह कोड काम नहीं कर रहा है – wonjun

+0

यह काम करता है "__declspec (dllexport)" के बिना ठीक है। धन्यवाद और फोर्ट्रान में, बहु-आयामी सरणी सीधे numpy दाएं से गुजर सकती है? fwrap .. वास्तव में मैं अजगर <-> सी, सी ++ <-> फोर्टन के बीच सरणी पास करने की तलाश में हूं। – wonjun