PythonでアクセスするためにSWIGを使用してラップする次のメソッドがあります。
void some_class::some_method( FILE *fp, int *pT, int **pO ) {
fscanf( fp, "lalala", pT );
最初の引数に StringIO を渡すにはどうすればよいですか? どのタイプマップを使用すればよいですか?
簡単な解決策は、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_AsFile
StringIOオブジェクトだけでなく実際にはファイルであるPythonFileオブジェクトを処理するための呼び出しを挿入することをお勧めします。戻り値をチェックして、実行可能なさまざまなタイプの入力として指定された引数を使用してみることができます。
これはかなり複雑です。より良い解決策はcStringIO
、代わりに使用することです。これにより、直接C APIが提供され、への呼び出しがgetvalue
完全に回避されます。glibcを使用している場合は、ゼロコピーのためにオブジェクトに直接fopencookie
フックするために使用できます。FILE*
cStringIO