簡単な答えは、2 つの入力を受け取るが、numinputs 属性が 1 に設定されている typemap を使用する必要があるということです。
%module test
%typemap(in,numinputs=1) (double *a, size_t) %{
assert(PyList_Check($input));
$2 = PyList_Size($input);
$1 = malloc(sizeof *$1 * $2);
for(size_t i = 0; i < $2; ++i) {
$1[i] = PyFloat_AsDouble(PyList_GetItem($input, i));
}
%}
%typemap(in, numinputs=1) (int *b, size_t) %{
assert(PyList_Check($input));
$2 = PyList_Size($input);
$1 = malloc(sizeof *$1 * $2);
for (size_t i = 0; i < $2; ++i) {
$1[i] = PyInt_AsLong(PyList_GetItem($input, i));
}
%}
%typemap(freearg) (double *a, size_t) %{
free($1);
%}
%typemap(freearg) (int *b, size_t) %{
free($1);
%}
%inline %{
double myfun(double *a, size_t n, int *b, size_t m) {
(void)a; (void) b;
printf("%d, %d\n", n, m);
for (size_t i = 0; i < (n > m ? n : m); ++i) {
printf("%d: %f - %d\n", i, i < n ? a[i] : 0, i < m ? b[i] : 0);
}
return 1.0;
}
%}
これは機能し、(array, len) の各ペアのタイプマップがあり、次のように使用するのに十分です:
import test
a = [0.5, 1.0, 1.5]
b = [1,2,3]
test.myfun(a,b)
alloca
または C99 の VLA 機能を使用して、malloc
呼び出しの必要性を回避することもできましたが、説明のためにこれが機能します。
(注:関数プロトタイプのどこにも書いていませんconst
が、それは入力配列を変更していないことを意味します。そうでない場合は、対応する argout typemap を記述して、割り当てられた配列からコピーする必要があります。 Python リストに追加されます)。
ただし、これは非常に反復的であるため、2 つの間でコードを共有できればより良いかもしれません。必要に応じて、より高度な SWIG 機能を使用して共有できます。必要に応じて、リストだけでなく、入力としてメモリ ビューのサポートを追加することもできます。