2012-07-25 43 views
0

我想替換MATLAB/MEX並切換到Python。我遇到了SWIG,ctypes & Cython作爲可能的解決方案並開始嘗試SWIG(這看起來很簡單)。閱讀可變參數長度的Python C包裝

我的C函數具有形式爲main(int argc, char *argv[])的可變參數長度。我在網上找到了解決方案,但與SWIG合作會導致很多問題。

  1. 其他方法(ctypes/Cython)是否更簡單?
  2. 任何使用SWIG完成此任務的示例都將有所幫助。

回答

4

有實際an example in the SWIG documentation是整整:

#include <stdio.h> 
void test(int n, char *argv[]) 
{ 
    int i; 
    for(i=0;i<n;i++) 
    { 
     printf("%s\n", argv[i]); 
    } 
} 

那麼你可以通過下面的Python代碼中調用這個C函數這種功能與Python。

%typemap(in) (int argc, char *argv[]) { 
    int i; 
    if (!PyList_Check($input)) { 
    PyErr_SetString(PyExc_ValueError, "Expecting a list"); 
    return NULL; 
    } 
    $1 = PyList_Size($input); 
    $2 = (char **) malloc(($1+1)*sizeof(char *)); 
    for (i = 0; i < $1; i++) { 
    PyObject *s = PyList_GetItem($input,i); 
    if (!PyString_Check(s)) { 
     free($2); 
     PyErr_SetString(PyExc_ValueError, "List items must be strings"); 
     return NULL; 
    } 
    $2[i] = PyString_AsString(s); 
    } 
    $2[i] = 0; 
} 

%typemap(freearg) (int argc, char *argv[]) { 
    free($2); // If here is uneeded, free(NULL) is legal 
} 

這可以讓你在Python簡單地做:

import test 
test.foo(["a", "b", "c"]) 

哪裏test是你給SWIG和模塊的名稱,我用一個小的改動在這裏引用它foo是一個與簽名int argc, char *argv[]匹配的函數。簡單直觀的用於Python程序員,它封裝和重用複雜的位。


文檔似乎什麼並不雖然提的是,有一個接口文件,該文件已經這樣做了一切爲您:

%module test 

%include <argcargv.i> 

%apply (int ARGC, char **ARGV) { (int argc, char *argv[]) } 

void foo(int argc, char *argv[]); 

就足夠了。

0

以下是使用ctypes的示例。

首先C代碼,不得更改的argv內容:

from ctypes import * 
dll = cdll.LoadLibrary("charpp_test.dll") 
argv = ["test1", "testtest2", "testtesttest3"] 
dll.test(len(argv), (c_char_p*len(argv))(*argv)) 
+0

謝謝。但是,如果我對.c文件進行了任何更改並嘗試使用python代碼,則此更改不起作用。我試圖在代碼的末尾「刪除dll」,但這沒有幫助。 如何卸載此dll? – SEU 2012-07-25 07:56:36