私はFILE *
に出力を書き込むことによって、テキストを生成する(Cで書かれた)ライブラリ関数を持っています。私はこれをPython(2.7.x)で、一時ファイルまたはパイプを作成し、関数に渡し、ファイルから結果を読み取り、Python文字列として返すコードでラップしたいと思います。パスFILE *
/* Library function */
void write_numbers(FILE * f, int arg1, int arg2)
{
fprintf(f, "%d %d\n", arg1, arg2);
}
Pythonラッパー:
from ctypes import *
mylib = CDLL('mylib.so')
def write_numbers(a, b):
rd, wr = os.pipe()
write_fp = MAGIC_HERE(wr)
mylib.write_numbers(write_fp, a, b)
os.close(wr)
read_file = os.fdopen(rd)
res = read_file.read()
read_file.close()
return res
#Should result in '1 2\n' being printed.
print write_numbers(1,2)
私は私の最善の策はMAGIC_HERE()
何のためにあるのか思ったんだけど
は、ここで私は後だものを説明するために単純化した例です。
私はを使用して、Python c_void_tを返すlibc.fdopen()
ラッパーを作成し、それをライブラリ関数に渡したいと思っています。私はそれが理論上安全であるべきだと思っています。このアプローチに問題があるのか、この問題を解決するための既存のPythonのアイムがあるのだろうかと思っています。
また、これは(単に、「永遠に」と仮定することができます)長時間実行プロセスになりますので、漏れたファイルディスクリプタは問題になるだろう。
'OSをディスクリプタ/ファイルオブジェクトには、他のI/Oを保証しません.popen() 'が間違っています。これには少なくとも1つの引数が必要です。コマンドラインを呼び出してパイプを取得する必要があります。また、[docs](https://docs.python.org/2/library/os.html?highlight=os.popen#os.popen)のように、 'サブプロセス 'の方が非難されています。 –
申し訳ありません、私は 'os.pipe()'を意味しました。更新しました。 –
Cランタイムライブラリの不一致の可能性があるWindows上でこれを実行する予定がない限り、 'libc.fdopen'を呼び出して結果の' FILE'ポインタを渡す際に問題はないと思います。しかし 'c_void_p'を使う代わりに、' class FILE(Structure):pass'を作成し、 'libc.fdopen.restype = POINTER(FILE)'を設定します。これは整数の結果に変換されません。 OTOHでは、 'restype'としての' c_void_p'が整数に変換されるので、 'mylib.write_numbers.argtypes'も64ビットのポインタ値を切り捨てないように設定する必要があります。 – eryksun