diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index f36b3d5a6..654ef04d8 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -34,6 +34,20 @@ private: NAMESPACE_BEGIN(detail) +/// Convert from any type pointer to another avoding warnings about void* vs (void*()) incompatibility. +template +A cast_any_ptr(B x) { return reinterpret_cast(reinterpret_cast(x)); } + +/// Return (*)(Args...) -> void* +template +void * func_to_voidp(Return (*f)(Args...)) { return cast_any_ptr(f); } + +/// void* -> Return (*)(Args...) +template +Return (*voidp_to_func(void * f))(Args...) { return cast_any_ptr(f); } + + + /// Additional type information which does not fit into the PyTypeObject struct type_info { PyTypeObject *type; diff --git a/include/pybind11/numpy.h b/include/pybind11/numpy.h index 3386876e5..8f1030a92 100644 --- a/include/pybind11/numpy.h +++ b/include/pybind11/numpy.h @@ -56,11 +56,11 @@ public: void **api_ptr = (void **) (c ? PyCObject_AsVoidPtr(c.ptr()) : nullptr); #endif API api; - api.PyArray_Type_ = (decltype(api.PyArray_Type_)) api_ptr[API_PyArray_Type]; - api.PyArray_DescrFromType_ = (decltype(api.PyArray_DescrFromType_)) api_ptr[API_PyArray_DescrFromType]; - api.PyArray_FromAny_ = (decltype(api.PyArray_FromAny_)) api_ptr[API_PyArray_FromAny]; - api.PyArray_NewCopy_ = (decltype(api.PyArray_NewCopy_)) api_ptr[API_PyArray_NewCopy]; - api.PyArray_NewFromDescr_ = (decltype(api.PyArray_NewFromDescr_)) api_ptr[API_PyArray_NewFromDescr]; + api.PyArray_Type_ = detail::cast_any_ptr (api_ptr[API_PyArray_Type]); + api.PyArray_DescrFromType_ = detail::cast_any_ptr (api_ptr[API_PyArray_DescrFromType]); + api.PyArray_FromAny_ = detail::cast_any_ptr (api_ptr[API_PyArray_FromAny]); + api.PyArray_NewCopy_ = detail::cast_any_ptr (api_ptr[API_PyArray_NewCopy]); + api.PyArray_NewFromDescr_ = detail::cast_any_ptr (api_ptr[API_PyArray_NewFromDescr]); return api; } diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 84510f19a..862f3d5b8 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -49,7 +49,7 @@ public: template cpp_function(Return (*f)(Args...), const Extra&... extra) { auto rec = new detail::function_record(); - rec->data = (void *) f; + rec->data = detail::func_to_voidp(f); typedef arg_value_caster cast_in; typedef return_value_caster cast_out; @@ -67,7 +67,7 @@ public: /* Do the call and convert the return value back into the Python domain */ handle result = cast_out::cast( - args.template call((Return (*) (Args...)) rec->data), + args.template call(detail::voidp_to_func(rec->data)), rec->policy, parent); /* Invoke call policy post-call hook */