2016-09-28 32 views
1

我有一個C++實現,用SWIG包裝並編譯爲一個可以被python使用的模塊。將ctypes int **轉換爲numpy 2維數組

我正在使用ctypes來調用帶有ctype參數的函數,int double等。 my_function(ctype args)的輸出是一個int **,即它是一個多維數組。

我怎樣才能把這個變成一個2D numpy數組在Python腳本內?我一直在看ctypes指針,但到目前爲止我沒有運氣。我已經花了很多很多時間閱讀Python的C-API和numpy以用於SWIG,並且在C++端實現返回一個numpy數組迄今非常困難並且完全不成功。

+0

看起來像一個重複的SWIG作出生成的代碼。這個答案呢? http://stackoverflow.com/questions/22425921/pass-a-2d-numpy-array-to-c-using-ctypes –

+0

這個問題似乎是這個問題的雙重性,@TheQuantumPhysicist(numpy - > int ** ,而不是int ** - > numpy) – Eric

+0

int **是動態分配的嗎? 「刪除[]」的工作是誰的? – Eric

回答

0

我不認爲這可以在Python方面完成;它必須在C/C++層使用NumPy的C-API接口完成(PyArray_SimpleNewFromData是相關功能 - 有關詳細信息,請參見this answer)。 Here是Cython腳本中的一個例子。

請注意,在這種情況下處理取消分配是複雜的:據我所知,沒有機制允許numpy自動處理它。你只需確保當numpy包裝仍在使用時,無論腳本何時釋放數組,都不會這樣做。

編輯:如果您的int**沒有指向連續的內存塊,我不相信這會起作用。 NumPy只能(輕鬆地)處理連續的數據緩衝區。

+0

這絕對可以在python一方完成(ctypes爲您提供了取消引用指針所需的所有機制),但您說得對,numpy僅適用於連續的數據緩衝區。當然,這是可能的(但不太可能)數據是連續的 – Eric

+0

我明白ctypes可以讓你操作指針,但我認爲你不能在Python方面調用numpy的''PyArray_SimpleNewFromData''(儘管我會很高興被證明是錯誤的!) – jakevdp

+0

我認爲[這個問題](https:// stackoverflow。com/questions/4355524/getting-data-from-ctypes-array-into-numpy)解決了一維情況,並且由於數據無論如何都是不相交的,這是您可以做的最好的。 – Eric

0

使用NumPy的和numpy.i,這是很容易的

接口頭

#pragma once 
void fun(int** outArray, int* nRows, int* nCols); 

實施

#include "test.h" 
#include <malloc.h> 
void fun(int** outArray, int* nRows, int* nCols) { 
    int _nRows = 100; 
    int _nCols = 150; 
    int* _outArray = (int*)malloc(sizeof(int)*_nRows*_nCols); 
    *outArray = _outArray; 
    *nRows = _nRows; 
    *nCols = _nCols; 
} 

SWIG接口頭

%module example 
%{ 
    #define SWIG_FILE_WITH_INIT 
    #include "test.h" 
%} 

%include "numpy.i" 

%init 
%{ 
    import_array(); 
%} 

%apply (int** ARGOUTVIEWM_ARRAY2, int* DIM1, int* DIM2) {(int** outArray, int* nRows, int* nCols)} 
%include "test.h" 

的噸ypemap ARGOUTVIEWM_ARRAY2創建一個託管的NumPy數組,當NumPy對象在Python中銷燬時,自動調用free。

如果你想創建使用Python C API自己的包裝,你可以考慮使用numpy.i