的使用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