![](/img/trans.png)
[英]Pass str as an int array to a Python C extended function (extended using SWIG)
[英]SWIG C-to-Python Int Array
我試圖使用swig從python中使用以下原型訪問C函數:
int cosetCoding(int writtenDataIn, int newData, const int memoryCells, int *cellFailure, int failedCell);
Swig創建.so沒有問題,我可以將它導入到python中,但是當我嘗試使用以下內容訪問它時:
cosetCoding.cosetCoding(10,11,8,[0,0,0,0,0,0,0,0],0)
我得到以下回溯:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: in method 'cosetCoding', argument 4 of type 'int *'
指針應該是一個int數組,其大小由memoryCells定義
如果可以,請使用ctypes。 它更簡單。 但是,既然你要求SWIG,你需要的是一個描述如何處理int *的類型映射。 SWIG不知道可以指出多少個整數。 以下是關於多參數類型地圖的SWIG文檔中的示例:
%typemap(in) (const int memoryCells, int *cellFailure) {
int i;
if (!PyList_Check($input)) {
PyErr_SetString(PyExc_ValueError, "Expecting a list");
return NULL;
}
$1 = PyList_Size($input);
$2 = (int *) malloc(($1)*sizeof(int));
for (i = 0; i < $1; i++) {
PyObject *s = PyList_GetItem($input,i);
if (!PyInt_Check(s)) {
free($2);
PyErr_SetString(PyExc_ValueError, "List items must be integers");
return NULL;
}
$2[i] = PyInt_AsLong(s);
}
}
%typemap(freearg) (const int memoryCells, int *cellFailure) {
if ($2) free($2);
}
請注意,使用此定義時,從Python調用時,請省略memoryCells
參數,並為memoryCells
傳遞[1,2,3,4]
等cellFailure
。 typemap將生成memoryCells
參數。
PS我可以發布一個完整的工作示例(對於Windows),如果你想要它。
馬克是對的,你需要一個打字機。 但是,如果使用numpy.i
(http://docs.scipy.org/doc/numpy/reference/swig.interface-file.html),則無需手動編寫類型映射,已經定義了必要的類型映射到將C轉換為NumPy數組,反之亦然。
在你的情況下(假設cellFailure
是一個輸入數組)你將要使用
%apply (int DIM1, int* IN_ARRAY1) {(int memoryCells, int *cellFailure)}
注意(正如Mark已經指出的那樣)這樣可以方便地將C中的這2個參數融合到單個python數組參數中,無需單獨傳遞數組長度。 您的電話將如下所示:
from numpy import asarray
cosetCoding.cosetCoding(10,11,asarray([0,0,0,0,0,0,0,0]),0)
您需要構造一個c_int
數組才能工作:
arr = (ctypes.c_int * 8)(0, 0, 0, 0, 0, 0, 0, 0)
cosetCoding.cosetCoding(10, 11, 8, arr, 0)
更新添加更完整的示例。 我在Python 2.6下使用ctypes 1.1.0版; 也許我們做的事情略有不同?
也許通過ctypes.byref(arr)
代替?
cosetCoding.cosetCoding(10, 11, 8, ctypes.byref(arr), 0)
共享對象: cosetCoding.c
#include <stdio.h>
int cosetCoding(int writtenDataIn, int newData, const int memoryCells, int *cellFailure, int failedCell)
{
printf("cellFailure: %d %d\n", cellFailure[0], cellFailure[1]);
}
編譯:
% gcc -shared -fPIC -o cosetCoding.so cosetCoding.c
Python腳本: test_coset.py
import ctypes
cosetCoding = ctypes.cdll.LoadLibrary('./cosetCoding.so')
arr = (ctypes.c_int * 8)(1, 2, 3, 4, 5, 6, 7, 8)
cosetCoding.cosetCoding(10, 11, 8, arr, 0)
輸出:
% python test_coset.py
cellFailure: 1 2
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.