簡體   English   中英

SWIG C-to-Python Int Array

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM