|
List Info
Thread: Boost Python and ctypes
|
|
| Boost Python and ctypes |
  United States |
2008-02-24 06:41:15 |
I am trying to bridge two libraries, one a C library bound
into python
using ctypes, and the other a C++ library using Boost
Python.
In the C++ library, I have a class similar to the following,
with a
member function that returns a pointer to an internal
buffer.
struct Test
{
float data[16];
float *get_data() {return data;}
}
I have wrapped this in a seeming logical way:
BOOST_MODULE(test) {
class_<Test>("Test")
.def("get_data", &Test::get_data,
return_value_policy< return_by_value >();
}
Which suffices to retrieve a "float *" instance
from Python. However, I
need to pass this pointer to a ctypes-bound function:
void some_function(float *);
I can call this function from python without any trouble,
using a
ctypes created buffer:
buffer = (c_float * 16)
some_function(buffer)
However, when I attempt to pass the result of get_data()
into this
function, ctypes causes an error because Boost Python's
"float *" type
does not match ctypes' POINTER(c_float) type. Equally,
ctypes' cast()
function doesn't work to coerce the pointer type, because it
doesn't
recognise the "float *" type either.
Does anyone have a workaround to coerce these types (which
each contain
the same underlying pointer) together?
Thanks in advance for any suggestions,
- Tristam
_______________________________________________
C++-sig mailing list
C++-sig python.org
http:
//mail.python.org/mailman/listinfo/c++-sig
|
|
| Re: Boost Python and ctypes |
  United States |
2008-02-26 13:34:24 |
I don't know how to integrate this into Boost.Python in a
clean way, but here
is a litter terminal example that can help:
>>> array = (ctypes.c_int * 3)(1,2,3)
>>> addr = ctypes.addressof(array)
>>> arrayPtr = ctypes.cast(addr,
ctypes.POINTER((ctypes.c_int)))
>>> array[0]
1
>>> arrayPtr[0]
1
So basically if you can get a long value into python
representing the address
of your float array you are good to go. This is done in
Python-Ogre by just
wrapping a manual cast function:
unsigned long castToAddress(float* ptr)
{
return (unsigned long)ptr;
}
A more permanent way to do this would be to change your
wrapper to execute
this code with Boost.Python's C++ python API interface (not
tested):
bp::object convertFloat(float* ptr)
{
bp::object ctypes = bp::import("ctypes");
bp::long addr((unsigned addr)ptr);
bp::object
pointerType(ctypes["POINTER"](ctypes["c_float
"]));
return ctypes["cast"](addr, pointerType);
}
I believe you can do this by specifying a manual to python
convert for the
"float*" type.
Hope that helps,
Joseph Lisee
_______________________________________________
C++-sig mailing list
C++-sig python.org
http:
//mail.python.org/mailman/listinfo/c++-sig
|
|
| Re: Boost Python and ctypes |

|
2008-02-26 14:49:41 |
|
Thank you for the prompt answer - that accomplishes exactly what I was trying to do!
I haven't had a lot of luck tracking down the hooks to add a manual conversion for 'float *' into the types registry, do you have any reference for that handy?
- Tristam On 26/02/2008, Joseph Lisee < jlisee gmail.com">jlisee gmail.com> wrote:
I don't know how to integrate this into Boost.Python in a clean way, but here is a litter terminal example that can help: >>> array = (ctypes.c_int * 3)(1,2,3) >>> addr = ctypes.addressof(array)
>>> arrayPtr = ctypes.cast(addr, ctypes.POINTER((ctypes.c_int))) >>> array[0] 1 >>> arrayPtr[0] 1 So basically if you can get a long value into python representing the address
of your float array you are good to go. This is done in Python-Ogre by just wrapping a manual cast function: unsigned long castToAddress(float* ptr) { return (unsigned long)ptr; } A more permanent way to do this would be to change your wrapper to execute
this code with Boost.Python's C++ python API interface (not tested): bp::object convertFloat(float* ptr) { bp::object ctypes = bp::import("ctypes"); bp::long addr((unsigned addr)ptr);
bp::object pointerType(ctypes["POINTER"](ctypes["c_float"])); return ctypes["cast"](addr, pointerType); } I believe you can do this by specifying a manual to python convert for the
"float*" type. Hope that helps, Joseph Lisee _______________________________________________ C++-sig mailing list C++-sig python.org">C++-sig python.org http://mail.python.org/mailman/listinfo/c++-sig
|
| Re: Boost Python and ctypes |
  United States |
2008-02-26 15:09:24 |
> Thank you for the prompt answer - that accomplishes
exactly what I was trying
to do!
> I haven't had a lot of luck tracking down the hooks to
add a manual conversion
for 'float *' into the types registry, do you have any
reference for that handy?
>
> - Tristam
No problem, I think this is what you are looking for:
http://www.boost.org/libs/python/doc/v2/to_pytho
n_converter.html
-Joseph Lisee
_______________________________________________
C++-sig mailing list
C++-sig python.org
http:
//mail.python.org/mailman/listinfo/c++-sig
|
|
| Re: Boost Python and ctypes |

|
2008-02-26 16:05:05 |
|
Now we are into the dizzying world of template error messages 
So I have a class Matrix, which exposes a pointer to float, and a conversion operator to POINTER(c_float):
struct Matrix { int test(); float *ptr(); };
struct ctypes_float_ptr
{ static PyObject *convert(float *ptr) { object ctypes = import("ctypes");
long_ addr((unsigned)ptr); object pointerType(ctypes["POINTER"](ctypes["c_float"]));
return ctypes["cast"](addr, pointerType).ptr(); }
};
BOOST_PYTHON_MODULE(math) { to_python_converter<float *, ctypes_float_ptr>();
class_<Matrix>("Matrix") .def("test", &Matrix::test) // this compiles fine
.def("ptr", &Matrix::ptr) // error here ; }
And the error is as follows:
src/math.cpp:146: error: no matching function for call to 'boost::python::class_<math::Matrix, boost::python::detail::not_specified, boost::python::detail::not_specified, boost::python::detail::not_specified>::def(const char [4], <unknown type>)'
Any pointers on where to go from here?
On 26/02/2008, Joseph Lisee < jlisee gmail.com">jlisee gmail.com> wrote:
> Thank you for the prompt answer - that accomplishes exactly what I was trying to do! > I haven't had a lot of luck tracking down the hooks to add a manual conversion for 'float *' into the types registry, do you have any reference for that handy?
> > - Tristam No problem, I think this is what you are looking for: http://www.boost.org/libs/python/doc/v2/to_python_converter.html
-Joseph Lisee
_______________________________________________ C++-sig mailing list C++-sig python.org">C++-sig python.org http://mail.python.org/mailman/listinfo/c++-sig
|
[1-5]
|
|
|
about | contact Other archives ( Real Estate discussion Medical topics )
|