TLDR: Is it possible to pass C++ pointer types through python converters?
Here I declared my MyStruct and pointer type for it PMYSTRUCT, converter template class PointerConverter and that python module:
#include <boost/python.hpp>
namespace py = boost::python;
template<class T, class Converter>
void from_python_converter()
{
py::converter::registry::push_back(&Converter::convertable, &Converter::construct, py::type_id<T>());
}
template<typename POINTER_TYPE>
class PointerConverter
{
public:
static void* convertable(PyObject *obj_ptr) // Detect: Is Pyhton object converatable?
{
static py::object ctypes_c_void_p = py::import("ctypes").attr("c_void_p");
return PyObject_IsInstance(obj_ptr, ctypes_c_void_p.ptr())? obj_ptr: nullptr;
}
static void construct(PyObject *obj_ptr, py::converter::rvalue_from_python_stage1_data *data) // From Python to POINTER_TYPE converter
{
auto storage = reinterpret_cast<py::converter::rvalue_from_python_storage<POINTER_TYPE>*>(data)->storage.bytes;
new(storage) POINTER_TYPE(reinterpret_cast<POINTER_TYPE>(uintptr_t(py::extract<uintptr_t>(py::object(py::handle<>(py::borrowed(obj_ptr))).attr("value")))));
data->convertible = storage;
}
struct MyStruct
{
...
};
typedef MyStruct* PMYSTRUCT;
void foo(PMYSTRUCT p)
{
...
}
BOOST_PYTHON_MODULE(module_name)
{
from_python_converter<PMYSTRUCT, PointerConverter<PMYSTRUCT>>();
py::def("foo", &foo);
}
As you see foo() was planned to receive PMYSTRUCT as an argument through the boost.python converter mechanism. But when I try to pass:
from module_name import foo
import ctypes
foo(ctypes.c_void_p(100))
I get the exception:
Boost.Python.ArgumentError: Python argument types in
module_name.foo(c_void_p)
did not match C++ signature:
foo(struct MyStruct * __ptr64)