1

PythonでアクセスするためにSWIGを使用してラップする次のメソッドがあります。

void some_class::some_method( FILE *fp, int *pT, int **pO ) {
    fscanf( fp, "lalala", pT );

最初の引数に StringIO を渡すにはどうすればよいですか? どのタイプマップを使用すればよいですか?

4

1 に答える 1

0

簡単な解決策は、fmemopenを自動的に作成するFILE*ために使用するタイプマップを作成することです。例を作成しました:

%module test
%include <typemaps.i>

%typemap(in) FILE *sb (PyObject *str=NULL) {
  str = PyObject_CallMethod($input, "getvalue", NULL);
  char *buf = NULL;
  int len = 0;
  PyString_AsStringAndSize(str, &buf, &len);
  $1 = fmemopen(buf, len, "r");
}

%typemap(freearg) FILE *sb {
  if ($1) fclose($1);
  Py_XDECREF(str$argnum);
}

%apply int *OUTPUT { int * i };

%inline %{
  void foo(FILE *sb, int *i) {
    fscanf(sb, "%d", i);
  }
%}

これには2つの部分があります。まず、保持しているデータにアクセスするためにでgetvalue呼び出すPythonCAPIがいくつかあります。StringIOこのバッファは少なくともと同じくらい存続する必要があるFILE*ため、追加の変数を導入し、完了したらクリーンアップする必要があります。

また、入力ではなく出力として%apply自動的に処理することもありました。int *iこれはおそらくあなたがやろうとしていることをするのに十分です。

これは、次のテストプログラムを実行するのに十分でした。

import StringIO
import test

buf=StringIO.StringIO("666")
print test.foo(buf)

インターフェイスをより汎用的にしたい場合は、PyFile_AsFileStringIOオブジェクトだけでなく実際にはファイルであるPythonFileオブジェクトを処理するための呼び出しを挿入することをお勧めします。戻り値をチェックして、実行可能なさまざまなタイプの入力として指定された引数を使用してみることができます。

これはかなり複雑です。より良い解決策はcStringIO、代わりに使用することです。これにより、直接C APIが提供され、への呼び出しがgetvalue完全に回避されます。glibcを使用している場合は、ゼロコピーのためにオブジェクトに直接fopencookieフックするために使用できます。FILE*cStringIO

于 2013-02-18T13:40:18.343 に答える