的使用StringIO的我有以下的方法,我換使用痛飲訪問它在Python:的Python和痛飲:到位FILE *
void some_class::some_method(FILE *fp, int *pT, int **pO) {
fscanf(fp, "lalala", pT);
怎麼可能傳遞一個StringIO的第一個論點?我應該使用哪種類型圖?
的使用StringIO的我有以下的方法,我換使用痛飲訪問它在Python:的Python和痛飲:到位FILE *
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);
}
%}
有兩個部分這一點,首先有一些Python的C API調用的StringIO
getvalue
,以獲得訪問所保存的數據。這個緩衝區至少需要和FILE*
一樣長,所以我們必須引入一個額外的變量並在完成後清理它。
我也使用%apply
自動將int *i
作爲輸出而不是輸入。這可能足以做你想做的事情。
這足以讓我運行下面的測試程序:
import StringIO
import test
buf=StringIO.StringIO("666")
print test.foo(buf)
如果你想使界面更加通用的,我建議將調用PyFile_AsFile
處理的Python文件對象真的是文件,而不僅僅是StringIO對象。您可以檢查返回值,嘗試將您提供的參數用作許多不同可行類型的輸入。
這是非常令人費解的。更好的解決方案是使用cStringIO
,這會給你一個直接的C API,完全避免了對getvalue
的調用。如果您使用的是glibc,則可以使用fopencookie
將FILE*
直接掛接到cStringIO
對象以進行零拷貝。
哇,謝謝你的廣泛答案! – warden 2013-02-20 08:37:04
完整性檢查:你只是從'FILE *'中讀取而不寫入它? – Flexo 2013-02-18 12:53:39
是的,只讀 – warden 2013-02-20 08:36:38