44#include < type_traits>
55
66#include < pybind11/pybind11.h>
7- #include < sip.h>
87
98#include < iostream>
109#include < pybind11/iostream.h>
1110
1211#include " ../pybind11_qt_holder.h"
1312
13+ struct _sipTypeDef ;
14+ typedef struct _sipTypeDef sipTypeDef;
15+
16+ struct _sipSimpleWrapper ;
17+ typedef struct _sipSimpleWrapper sipSimpleWrapper;
18+
19+ struct _sipWrapper ;
20+ typedef struct _sipWrapper sipWrapper;
21+
1422namespace pybind11 ::detail::qt {
1523
16- /* *
17- * @brief Retrieve the SIP api.
18- *
19- * @return const sipAPIDef*
20- */
21- const sipAPIDef* sipAPI ();
24+ // helper functions to avoid bringing <sip.h> in this header
25+ namespace sip {
26+
27+ // extract the underlying data if present from the equivalent PyQt object
28+ void * extract_data (PyObject*);
29+
30+ const sipTypeDef* api_find_type (const char * type);
31+ int api_can_convert_to_type (PyObject* pyObj, const sipTypeDef* td, int flags);
32+
33+ void api_transfer_to (PyObject* self, PyObject* owner);
34+ void api_transfer_back (PyObject* self);
35+ PyObject* api_convert_from_type (void * cpp, const sipTypeDef* td,
36+ PyObject* transferObj);
37+ } // namespace sip
2238
2339 template <typename T, class = void >
2440 struct MetaData ;
@@ -91,12 +107,11 @@ namespace pybind11::detail::qt {
91107 }
92108 }
93109
94- const sipTypeDef* type =
95- qt::sipAPI ()->api_find_type (MetaData<QClass>::class_name);
110+ const auto * type = sip::api_find_type (MetaData<QClass>::class_name);
96111 if (type == nullptr ) {
97112 return false ;
98113 }
99- if (!qt::sipAPI ()-> api_can_convert_to_type (src.ptr (), type, 0 )) {
114+ if (!sip:: api_can_convert_to_type (src.ptr (), type, 0 )) {
100115 return false ;
101116 }
102117
@@ -107,20 +122,14 @@ namespace pybind11::detail::qt {
107122 //
108123 // sipAPI()->api_transfer_to(objPtr, Py_None);
109124 //
110- void * data = nullptr ;
111- if (PyObject_TypeCheck (src.ptr (), qt::sipAPI ()->api_simplewrapper_type )) {
112- data = reinterpret_cast <sipSimpleWrapper*>(src.ptr ())->data ;
113- }
114- else if (PyObject_TypeCheck (src.ptr (), qt::sipAPI ()->api_wrapper_type )) {
115- data = reinterpret_cast <sipWrapper*>(src.ptr ())->super .data ;
116- }
125+ void * const data = sip::extract_data (src.ptr ());
117126
118127 if (data) {
119128 if constexpr (is_pointer) {
120129 value = reinterpret_cast <QClass>(data);
121130
122131 // transfer ownership
123- sipAPI ()-> api_transfer_to (src.ptr (), Py_None);
132+ sip:: api_transfer_to (src.ptr (), Py_None);
124133
125134 // tie the py::object to the C++ one
126135 new pybind11::detail::qt::qobject_holder_impl (value);
@@ -164,8 +173,7 @@ namespace pybind11::detail::qt {
164173 }
165174 }
166175
167- const sipTypeDef* type =
168- qt::sipAPI ()->api_find_type (MetaData<QClass>::class_name);
176+ const sipTypeDef* type = sip::api_find_type (MetaData<QClass>::class_name);
169177 if (type == nullptr ) {
170178 return Py_None;
171179 }
@@ -188,19 +196,19 @@ namespace pybind11::detail::qt {
188196 sipData = &src;
189197 }
190198
191- sipObj = qt::sipAPI ()-> api_convert_from_type (sipData, type, 0 );
199+ sipObj = sip:: api_convert_from_type (sipData, type, 0 );
192200
193201 if (sipObj == nullptr ) {
194202 return Py_None;
195203 }
196204
197205 // ensure Python deletes the C++ component
198206 if constexpr (!is_pointer) {
199- qt::sipAPI ()-> api_transfer_back (sipObj);
207+ sip:: api_transfer_back (sipObj);
200208 }
201209 else {
202210 if (policy == return_value_policy::take_ownership) {
203- qt::sipAPI ()-> api_transfer_back (sipObj);
211+ sip:: api_transfer_back (sipObj);
204212 }
205213 }
206214
0 commit comments