[C++-sig] interfacing headle binary file library, raw pointer and buffer
heroxbd at gmail.com
heroxbd at gmail.com
Sun Jun 20 08:39:55 CEST 2010
Dear all,
I am trying to interface a binary file library using py++.
There is a function in the library like
int read(void* buffer, size_t len)
which is hard to wrap. It read a piece (size len) of the file, and store
it in buffer, and then return the buffer length (most likely equal to len).
If I do nothing special, the py++ generated module would be like:
,----
| >>> s = ""
| >>> l = 1
| >>> binary_file.read(s, l)
| ....
| did not match C++ signature:
| (python str type could not match void*)
`----
Here are what I have tried (with no success):
1. I found the keyword "opaque pointer" in boost.python and py++. My
knowledge is so limited that I couldn't figure out if my case is
_actually_ an opaque pointer problem, cuz all the documentation[1] for
py++ and boost.python are talking about opaque return pointer, not a
passed pointer. I poked around py++ to add some class policies (from the
example of gmp wrapper) resulting in no change in the py++ generated
boost.python code.
2. Then I tried to change the function to
int read(char* buffer, size_t len)
with type casting done internally in c++. Then
,----
| >>> s = ""
| >>> l = 1
| >>> binary_file.read(s, l)
| 1
| (the function executed successfully, with no c++ signature type mismatch)
| >>> s
| Segment Fault (python crash)
`----
maybe it is the methodology of python that not touching "low level" mem
management. I guess that's what making this problem non-trivial.
I may recompile my python with debugging information an trace it with
gdb to find out why it is crashing. But not yet.
3. I tried ctypes:
,----
| >>> s = ctypes.c_char_p
| >>> l = 1
| >>> binary_file.read(s, l)
| (c++ signature type mismatch)
`----
I guess we just cannot mix ctypes with boost.python directly.
Now I need to learn and try something new to solve this issue. After
some web searching, I find some possiblities:
1. py++ ctypes integration[2]. It looks promising. I would like to
confirm on this list if it is suited to my case.
2. write a wrapper like
,----
| struct void_p {
| void * ptr
| }
`----
and then change all the original c++ interface from func(void * buf,
...) to func(void_p buf, ...) (there are around 6 such functions) and
take care of the internal convertion by hand. But in this case the
interface becomes thicker. I regard it as the last choice cuz I want to
keep new c++ code minimum (hopefully all auto generated by py++).
3. I came across struct module[3] in python. It seems to suit my
needs; I'm not sure. I couldn't figure out how to use it right now.
4. pyOgre might have been already solved this kind of raw memory
problem. I could learn pyOgre team's example and apply their method to
my case. There may be a sharp learning curve though.
... I am not sure which path I should take.
I am a beginner in c++ and python and c++/python integration. The
documentations and mailing list archives seems overwhelming to me. I
couldn't find a fresh point to start digging into.
Please give me some suggestion and advice. I am ready to learn and try
and practise.
Cheers!
Benda
footnotes:
1. http://www.boost.org/doc/libs/1_43_0/libs/python/doc/v2/opaque.html
http://language-binding.net/pyplusplus/documentation/functions/call_policies/call_policies.html
2. http://language-binding.net/pyplusplus/documentation/ctypes/ctypes_integration.html
3. http://docs.python.org/library/struct.html
--
XU Benda
Research Center for Neutrino Science
Tohoku University
JAPAN
http://www.awa.tohoku.ac.jp/~benda
More information about the Cplusplus-sig
mailing list