2012-01-09 44 views
6

Tôi có thể chuyển mảng một chiều tới python như dưới đây. và tôi tự hỏi nếu tôi có thể vượt qua c + + mảng con trỏ đôi để python bằng cách sử dụng ctypes, numpy.truyền con trỏ kép C++ tới 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

Đây là một hack tôi đã được dạy, nhưng tại sao không chỉ vượt qua các con trỏ số nguyên dài? –

+0

vì loại có thể gấp đôi .. vv không chỉ số nguyên. – wonjun

+0

Các con trỏ luôn có thể được biểu diễn dưới dạng số nguyên dài. và sau đó quay trở lại bất kỳ loại nào bạn muốn. –

Trả lời

6

Đây là một cách. Tôi không nhìn thấy một cách tốt đẹp để sử dụng numpy với đôi **.

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

Tôi gặp lỗi khi tạo tệp ".so" test.cpp: 4: 1: error: constructor dự kiến, destructor hoặc chuyển đổi kiểu trước '(' token – wonjun

+0

Tôi đang trên linux vì vậy mã này không hoạt động – wonjun

+0

tốt mà không có "__declspec (dllexport)", cảm ơn và trong fortran, mảng đa chiều có thể được truyền trực tiếp với numpy phải không? fwrap .. thực sự tôi đang tìm kiếm mảng đi qua trong python <-> c, C++ <-> fortran – wonjun

Các vấn đề liên quan