0

MATLAB / MEXを置き換えて、Pythonに切り替えようとしています。私は可能な解決策としてSWIG、ctypes、Cythonに出会い、SWIGを試し始めました(これは非常に単純なようです)。

私のC関数には、の形式の可変引数長がありますmain(int argc, char *argv[])。オンラインで解決策を見つけましたが、これをSWIGで機能させると、多くの問題が発生します。

  1. 他の方法(ctypes / Cython)はもっと簡単ですか?
  2. SWIGを使用してこのタスクを実行する例があれば役立ちます。
4

2 に答える 2

6

実際、 Python を使用したまさにこの種の関数の例が SWIG ドキュメントにあります。マイナーな変更を加えてここに引用しました:

%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"])

はSWIGtestに付けたモジュールの名前で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[]);

十分なものです。

于 2012-07-25T08:58:06.933 に答える
0

これは ctypes を使用したサンプルです。

最初の c コードは、argv の内容を変更してはなりません。

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

次に、次の python コードでこの c 関数を呼び出すことができます。

from ctypes import *
dll = cdll.LoadLibrary("charpp_test.dll") 
argv = ["test1", "testtest2", "testtesttest3"]
dll.test(len(argv), (c_char_p*len(argv))(*argv))
于 2012-07-25T01:02:05.583 に答える