Hi, I am using Boost Python V2 to wrap my C++ code. I failed to convert python file to/from C++ FILE*. Here is my code: ---------------------------------------- struct FILE_to_pyfile { static PyObject* convert(FILE* x) { return PyFile_FromFile(x, "", "", NULL); } }; FILE* getfile(const char* fname) { printf("openning file: %s\n", fname); FILE* f = fopen(fname, "w"); fprintf(f, "initial words\n"); return f; } BOOST_PYTHON_MODULE(numbermod) { python::to_python_converter<FILE*, FILE_to_pyfile>(); python::def("getfile", getfile, python::return_internal_reference<>()); } ----------------------------------------------- After I compiled the code, in python run f = getfile("hello.txt") gave me the following error: Traceback (most recent call last): File "./test.py", line 18, in ? f1 = getfile("hello.txt") TypeError: bad argument type for built-in operation Can you kindly tell me 1) what's wrong with the above code? 2) The above code is from C++ 'FILE*' to python file. If I want to convert python file to C++ file, how can I do that? Thanks in advance. Liwei
Liwei Peng <lpeng@bcm.tmc.edu> writes:
Hi,
I am using Boost Python V2 to wrap my C++ code. I failed to convert python file to/from C++ FILE*. Here is my code:
---------------------------------------- struct FILE_to_pyfile { static PyObject* convert(FILE* x) { return PyFile_FromFile(x, "", "", NULL); } };
FILE* getfile(const char* fname) { printf("openning file: %s\n", fname); FILE* f = fopen(fname, "w"); fprintf(f, "initial words\n"); return f; }
BOOST_PYTHON_MODULE(numbermod) { python::to_python_converter<FILE*, FILE_to_pyfile>(); python::def("getfile", getfile, python::return_internal_reference<>()); }
----------------------------------------------- After I compiled the code, in python run
f = getfile("hello.txt")
gave me the following error:
Traceback (most recent call last): File "./test.py", line 18, in ? f1 = getfile("hello.txt") TypeError: bad argument type for built-in operation
Can you kindly tell me 1) what's wrong with the above code?
The problem is that when converting a pointer to python, Boost.Python looks up a converter for the _pointee_. So you need to register a to_python converter for FILE, not FILE*. This should probably be a lot clearer in my documentation than it is right now. So I suggest as a first step: struct FILE_to_pyfile { static PyObject* convert(FILE const& x) { return PyFile_FromFile(&x, "", "", NULL); } }; FILE* getfile(const char* fname) { printf("openning file: %s\n", fname); FILE* f = fopen(fname, "w"); fprintf(f, "initial words\n"); return f; } BOOST_PYTHON_MODULE(numbermod) { python::to_python_converter<FILE, FILE_to_pyfile>(); python::def("getfile", getfile, python::return_value_policy<reference_existing_object>()); } However, this is really not the best arrangement, since it shouldn't be neccessary to use return_value_policy<reference_existing_object> for FILE*. Probably we should add converter specializations for FILE* just as we have got for the builtin types.
2) The above code is from C++ 'FILE*' to python file. If I want to convert python file to C++ file, how can I do that?
You need to register an lvalue converter for FILE. Something like: struct pyfile_to_FILE { static File& execute(PyObject& o) { return *PyFile_AsFile(&o); } } // In your module init function lvalue_from_pytype<pyfile_to_FILE,&PyFile_Type>(); But again, I think these should probably be done by the library, through specialization rather than dynamically registered converters. HTH, -- David Abrahams dave@boost-consulting.com * http://www.boost-consulting.com
participants (2)
-
David Abrahams -
Liwei Peng