aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cppgenerator.cpp21
-rw-r--r--libshiboken/basewrapper.cpp134
-rw-r--r--libshiboken/basewrapper.h18
-rw-r--r--libshiboken/basewrapper_p.h139
-rw-r--r--libshiboken/bindingmanager.cpp27
-rw-r--r--libshiboken/bindingmanager.h2
-rw-r--r--libshiboken/conversions.h13
7 files changed, 305 insertions, 49 deletions
diff --git a/cppgenerator.cpp b/cppgenerator.cpp
index 650c3ee04..277b6f7ce 100644
--- a/cppgenerator.cpp
+++ b/cppgenerator.cpp
@@ -646,7 +646,6 @@ void CppGenerator::writeConstructorWrapper(QTextStream& s, const AbstractMetaFun
if (overloadData.hasAllowThread())
s << INDENT << "Shiboken::ThreadStateSaver " << THREAD_STATE_SAVER_VAR << ';' << endl;
s << INDENT << "SbkBaseWrapper* sbkSelf = reinterpret_cast<SbkBaseWrapper*>(self);" << endl;
- s << INDENT << "assert(!sbkSelf->cptr);\n"; // FIXME: object reinitialization not supported
if (metaClass->isAbstract() || metaClass->baseClassNames().size() > 1) {
s << INDENT << "SbkBaseWrapperType* type = reinterpret_cast<SbkBaseWrapperType*>(self->ob_type);" << endl;
@@ -690,19 +689,18 @@ void CppGenerator::writeConstructorWrapper(QTextStream& s, const AbstractMetaFun
writeOverloadedMethodDecisor(s, &overloadData);
s << endl;
+ s << INDENT << "if (PyErr_Occurred() || !Shiboken::setCppPointer(sbkSelf, Shiboken::SbkType<" << metaClass->qualifiedCppName() << " >(), cptr)) {" << endl;
+ {
+ Indentation indent(INDENT);
+ s << INDENT << "delete cptr;" << endl;
+ s << INDENT << "return " << m_currentErrorCode << ';' << endl;
+ }
+ s << INDENT << '}' << endl;
if (overloadData.maxArgs() > 0) {
- s << INDENT << "if (PyErr_Occurred()) {" << endl;
- {
- Indentation indent(INDENT);
- s << INDENT << "delete cptr;" << endl;
- s << INDENT << "return " << m_currentErrorCode << ';' << endl;
- }
- s << INDENT << '}' << endl;
s << INDENT << "if (!cptr) goto " << cpythonFunctionName(rfunc) << "_TypeError;" << endl;
s << endl;
}
- s << INDENT << "sbkSelf->cptr = cptr;" << endl;
s << INDENT << "sbkSelf->validCppObject = 1;" << endl;
// If the created C++ object has a C++ wrapper the ownership is assigned to Python
// (first "1") and the flag indicating that the Python wrapper holds an C++ wrapper
@@ -712,7 +710,7 @@ void CppGenerator::writeConstructorWrapper(QTextStream& s, const AbstractMetaFun
s << INDENT << "sbkSelf->containsCppWrapper = 1;" << endl;
if (needsReferenceCountControl(metaClass))
s << INDENT << "sbkSelf->referredObjects = new Shiboken::RefCountMap;" << endl;
- s << INDENT << "BindingManager::instance().registerWrapper(sbkSelf);" << endl;
+ s << INDENT << "BindingManager::instance().registerWrapper(sbkSelf, cptr);" << endl;
// Constructor code injections, position=end
if (hasCodeInjectionsAtEnd) {
@@ -1935,7 +1933,8 @@ void CppGenerator::writeClassDefinition(QTextStream& s, const AbstractMetaClass*
s << INDENT << "/*obj_copier*/ " << obj_copier << ',' << endl;
s << INDENT << "/*ext_isconvertible*/ 0," << endl;
s << INDENT << "/*ext_tocpp*/ 0," << endl;
- s << INDENT << "/*cpp_dtor*/ " << cpp_dtor << endl;
+ s << INDENT << "/*cpp_dtor*/ " << cpp_dtor << ',' << endl;
+ s << INDENT << "/*is_multicpp*/ 0" << endl;
s << "};" << endl;
}
diff --git a/libshiboken/basewrapper.cpp b/libshiboken/basewrapper.cpp
index 620021700..9fa7e7ef6 100644
--- a/libshiboken/basewrapper.cpp
+++ b/libshiboken/basewrapper.cpp
@@ -33,11 +33,13 @@
*/
#include "basewrapper.h"
+#include "basewrapper_p.h"
#include <cstddef>
#include <algorithm>
#include "autodecref.h"
#include "typeresolver.h"
#include <string>
+#include <cstring>
namespace Shiboken
{
@@ -137,18 +139,42 @@ PyObject* SbkBaseWrapper_New(SbkBaseWrapperType* instanceType,
instanceType = instanceType->type_discovery->getType(cptr, instanceType);
SbkBaseWrapper* self = reinterpret_cast<SbkBaseWrapper*>(SbkBaseWrapper_TpNew(reinterpret_cast<PyTypeObject*>(instanceType), 0, 0));
- self->cptr = const_cast<void*>(cptr);
+ self->cptr[0] = cptr;
self->hasOwnership = hasOwnership;
self->validCppObject = 1;
- BindingManager::instance().registerWrapper(self);
+ BindingManager::instance().registerWrapper(self, cptr);
return reinterpret_cast<PyObject*>(self);
}
+void walkThroughClassHierarchy(PyTypeObject* currentType, HierarchyVisitor* visitor)
+{
+ PyObject* bases = currentType->tp_bases;
+ Py_ssize_t numBases = PyTuple_GET_SIZE(bases);
+ for (int i = 0; i < numBases; ++i) {
+ PyTypeObject* type = reinterpret_cast<PyTypeObject*>(PyTuple_GET_ITEM(bases, i));
+
+ if (type->ob_type != &Shiboken::SbkBaseWrapperType_Type) {
+ continue;
+ } else {
+ SbkBaseWrapperType* sbkType = reinterpret_cast<SbkBaseWrapperType*>(type);
+ if (sbkType->is_multicpp)
+ walkThroughClassHierarchy(type, visitor);
+ else
+ visitor->visit(sbkType);
+ }
+ if (visitor->wasFinished())
+ return;
+ }
+}
+
PyObject* SbkBaseWrapper_TpNew(PyTypeObject* subtype, PyObject*, PyObject*)
{
Shiboken::AutoDecRef emptyTuple(PyTuple_New(0));
SbkBaseWrapper* self = reinterpret_cast<SbkBaseWrapper*>(PyBaseObject_Type.tp_new(subtype, emptyTuple, 0));
- self->cptr = 0;
+
+ int numBases = reinterpret_cast<SbkBaseWrapperType*>(subtype)->is_multicpp ? getNumberOfCppBaseClasses(subtype) : 1;
+ self->cptr = new void*[numBases];
+ std::memset(self->cptr, 0, sizeof(void*)*numBases);
self->hasOwnership = 1;
self->containsCppWrapper = 0;
self->validCppObject = 0;
@@ -159,6 +185,30 @@ PyObject* SbkBaseWrapper_TpNew(PyTypeObject* subtype, PyObject*, PyObject*)
return reinterpret_cast<PyObject*>(self);
}
+void* getCppPointer(PyObject* wrapper, PyTypeObject* desiredType)
+{
+ PyTypeObject* type = wrapper->ob_type;
+ int idx = 0;
+ if (reinterpret_cast<SbkBaseWrapperType*>(type)->is_multicpp)
+ idx = getTypeIndexOnHierarchy(type, desiredType);
+ return reinterpret_cast<Shiboken::SbkBaseWrapper*>(wrapper)->cptr[idx];
+}
+
+bool setCppPointer(SbkBaseWrapper* wrapper, PyTypeObject* desiredType, void* cptr)
+{
+ int idx = 0;
+ if (reinterpret_cast<SbkBaseWrapperType*>(wrapper->ob_type)->is_multicpp)
+ idx = getTypeIndexOnHierarchy(wrapper->ob_type, desiredType);
+
+ bool alreadyInitialized = wrapper->cptr[idx];
+ if (alreadyInitialized)
+ PyErr_SetString(PyExc_RuntimeError, "You can't initialize an object twice!");
+ else
+ wrapper->cptr[idx] = cptr;
+
+ return !alreadyInitialized;
+}
+
bool cppObjectIsInvalid(PyObject* wrapper)
{
if (wrapper == Py_None
@@ -172,7 +222,6 @@ bool cppObjectIsInvalid(PyObject* wrapper)
void SbkBaseWrapper_Dealloc_PrivateDtor(PyObject* self)
{
-
if (((SbkBaseWrapper *)self)->weakreflist)
PyObject_ClearWeakRefs(self);
@@ -222,6 +271,41 @@ bool importModule(const char* moduleName, PyTypeObject*** cppApiPtr)
// Wrapper metatype and base type ----------------------------------------------------------
+class DtorCallerVisitor : public HierarchyVisitor
+{
+public:
+ DtorCallerVisitor(SbkBaseWrapper* pyObj) : m_count(0), m_pyObj(pyObj) {}
+ virtual void visit(SbkBaseWrapperType* node)
+ {
+ node->cpp_dtor(m_pyObj->cptr[m_count]);
+ m_count++;
+ }
+private:
+ int m_count;
+ SbkBaseWrapper* m_pyObj;
+};
+
+static void deallocPythonTypes(PyObject* pyObj)
+{
+ SbkBaseWrapper* sbkObj = reinterpret_cast<SbkBaseWrapper*>(pyObj);
+ if (sbkObj->weakreflist)
+ PyObject_ClearWeakRefs(pyObj);
+
+ BindingManager::instance().releaseWrapper(pyObj);
+ if (SbkBaseWrapper_hasOwnership(sbkObj)) {
+ DtorCallerVisitor visitor(sbkObj);
+ walkThroughClassHierarchy(pyObj->ob_type, &visitor);
+ }
+
+ if (SbkBaseWrapper_hasParentInfo(sbkObj))
+ destroyParentInfo(sbkObj);
+ SbkBaseWrapper_clearReferences(sbkObj);
+
+ delete[] sbkObj->cptr;
+ sbkObj->cptr = 0;
+ Py_TYPE(pyObj)->tp_free(pyObj);
+}
+
void deallocWrapper(PyObject* pyObj)
{
SbkBaseWrapper* sbkObj = reinterpret_cast<SbkBaseWrapper*>(pyObj);
@@ -231,15 +315,15 @@ void deallocWrapper(PyObject* pyObj)
BindingManager::instance().releaseWrapper(pyObj);
if (SbkBaseWrapper_hasOwnership(pyObj)) {
SbkBaseWrapperType* sbkType = reinterpret_cast<SbkBaseWrapperType*>(pyObj->ob_type);
- assert(!sbkType->is_python_type);
- sbkType->cpp_dtor(sbkObj->cptr);
+ assert(!sbkType->is_multicpp);
+ sbkType->cpp_dtor(sbkObj->cptr[0]);
}
if (SbkBaseWrapper_hasParentInfo(pyObj))
destroyParentInfo(sbkObj);
SbkBaseWrapper_clearReferences(sbkObj);
- delete sbkObj->cptr;
+ delete[] sbkObj->cptr;
sbkObj->cptr = 0;
Py_TYPE(pyObj)->tp_free(pyObj);
}
@@ -253,17 +337,31 @@ SbkBaseWrapperType_TpNew(PyTypeObject* metatype, PyObject* args, PyObject* kwds)
if (!newType)
return 0;
- // This expects that Python classes will inherit from only one C++ wrapped class.
- SbkBaseWrapperType* parentType = reinterpret_cast<SbkBaseWrapperType*>(PyTuple_GET_ITEM(PyTuple_GET_ITEM(args, 1), 0));
-
- newType->mi_offsets = parentType->mi_offsets;
- newType->mi_init = parentType->mi_init;
- newType->mi_specialcast = parentType->mi_specialcast;
- newType->ext_isconvertible = parentType->ext_isconvertible;
- newType->ext_tocpp = parentType->ext_tocpp;
- newType->type_discovery = parentType->type_discovery;
- newType->obj_copier = parentType->obj_copier;
-
+ std::list<SbkBaseWrapperType*> bases = getCppBaseClasses(reinterpret_cast<PyTypeObject*>(newType));
+ if (bases.size() == 1) {
+ SbkBaseWrapperType* parentType = bases.front();
+ newType->super.ht_type.tp_dealloc = parentType->super.ht_type.tp_dealloc;
+ newType->mi_offsets = parentType->mi_offsets;
+ newType->mi_init = parentType->mi_init;
+ newType->mi_specialcast = parentType->mi_specialcast;
+ newType->ext_isconvertible = parentType->ext_isconvertible;
+ newType->ext_tocpp = parentType->ext_tocpp;
+ newType->type_discovery = parentType->type_discovery;
+ newType->obj_copier = parentType->obj_copier;
+ newType->cpp_dtor = parentType->cpp_dtor;
+ newType->is_multicpp = 0;
+ } else {
+ newType->super.ht_type.tp_dealloc = &deallocPythonTypes;
+ newType->mi_offsets = 0;
+ newType->mi_init = 0;
+ newType->mi_specialcast = 0;
+ newType->ext_isconvertible = 0;
+ newType->ext_tocpp = 0;
+ newType->type_discovery = 0;
+ newType->obj_copier = 0;
+ newType->cpp_dtor = 0;
+ newType->is_multicpp = 1;
+ }
return reinterpret_cast<PyObject*>(newType);
}
diff --git a/libshiboken/basewrapper.h b/libshiboken/basewrapper.h
index b47a5cd50..c2b1e616a 100644
--- a/libshiboken/basewrapper.h
+++ b/libshiboken/basewrapper.h
@@ -111,6 +111,8 @@ struct LIBSHIBOKEN_API SbkBaseWrapperType
ExtendedToCppFunc ext_tocpp;
/// Pointer to a function responsible for deletetion of the C++ instance calling the proper destructor.
void (*cpp_dtor)(void*);
+ /// True if this type holds two or more C++ instances, e.g.: a Python class which inherits from two C++ classes.
+ int is_multicpp:1;
};
/// Base Python object for all the wrapped C++ classes.
@@ -118,7 +120,7 @@ struct LIBSHIBOKEN_API SbkBaseWrapper
{
PyObject_HEAD
/// Pointer to the C++ class.
- void* cptr;
+ void** cptr;
/// Instance dictionary.
PyObject* ob_dict;
/// True when Python is responsible for freeing the used memory.
@@ -171,6 +173,16 @@ inline bool isShibokenType(const PyObject* pyObj)
}
/**
+* Get the C++ pointer of type \p desiredType from a Python object.
+*/
+LIBSHIBOKEN_API void* getCppPointer(PyObject* wrapper, PyTypeObject* desiredType);
+
+/**
+* Set the C++ pointer of type \p desiredType of a Python object.
+*/
+LIBSHIBOKEN_API bool setCppPointer(SbkBaseWrapper* wrapper, PyTypeObject* desiredType, void* cptr);
+
+/**
* Shiboken_TypeCheck macro performs a type check using the values registered with SbkType<>() template.
*/
#define Shiboken_TypeCheck(pyobj, type) (PyObject_TypeCheck(pyobj, SbkType<type>()))
@@ -178,8 +190,6 @@ inline bool isShibokenType(const PyObject* pyObj)
#define SbkBaseWrapper_Check(op) PyObject_TypeCheck(op, (PyTypeObject*)&Shiboken::SbkBaseWrapper_Type)
#define SbkBaseWrapper_CheckExact(op) ((op)->ob_type == &Shiboken::SbkBaseWrapper_Type)
-#define SbkBaseWrapper_cptr(pyobj) (((Shiboken::SbkBaseWrapper*)pyobj)->cptr)
-#define SbkBaseWrapper_setCptr(pyobj,c) (((Shiboken::SbkBaseWrapper*)pyobj)->cptr = c)
#define SbkBaseWrapper_instanceDict(pyobj) (((Shiboken::SbkBaseWrapper*)pyobj)->ob_dict)
#define SbkBaseWrapper_setInstanceDict(pyobj,d) (((Shiboken::SbkBaseWrapper*)pyobj)->ob_dict = d)
#define SbkBaseWrapper_hasOwnership(pyobj) (((Shiboken::SbkBaseWrapper*)pyobj)->hasOwnership)
@@ -222,8 +232,10 @@ LIBSHIBOKEN_API void SbkBaseWrapper_clearReferences(SbkBaseWrapper* self);
/// Returns true and sets a Python RuntimeError if the Python wrapper is not marked as valid.
LIBSHIBOKEN_API bool cppObjectIsInvalid(PyObject* wrapper);
+/// Dealloc the python object \p pyObj and the C++ object represented by it.
LIBSHIBOKEN_API void deallocWrapper(PyObject* pyObj);
+/// Delete the class T allocated on \p cptr.
template<typename T>
void callCppDestructor(void* cptr)
{
diff --git a/libshiboken/basewrapper_p.h b/libshiboken/basewrapper_p.h
new file mode 100644
index 000000000..555f40d49
--- /dev/null
+++ b/libshiboken/basewrapper_p.h
@@ -0,0 +1,139 @@
+/*
+* This file is part of the Shiboken Python Bindings Generator project.
+*
+* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+*
+* Contact: PySide team <contact@pyside.org>
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public License
+* version 2.1 as published by the Free Software Foundation. Please
+* review the following information to ensure the GNU Lesser General
+* Public License version 2.1 requirements will be met:
+* http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+*
+* As a special exception to the GNU Lesser General Public License
+* version 2.1, the object code form of a "work that uses the Library"
+* may incorporate material from a header file that is part of the
+* Library. You may distribute such object code under terms of your
+* choice, provided that the incorporated material (i) does not exceed
+* more than 5% of the total size of the Library; and (ii) is limited to
+* numerical parameters, data structure layouts, accessors, macros,
+* inline functions and templates.
+*
+* This program is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA
+*/
+
+#ifndef BASEWRAPPER_P_H
+#define BASEWRAPPER_P_H
+
+#include <Python.h>
+#include <list>
+
+namespace Shiboken
+{
+
+struct SbkBaseWrapperType;
+
+/**
+* Visitor class used by walkOnClassHierarchy function.
+*/
+class HierarchyVisitor
+{
+public:
+ HierarchyVisitor() : m_wasFinished(false) {}
+ virtual ~HierarchyVisitor() {}
+ virtual void visit(SbkBaseWrapperType* node) = 0;
+ void finish() { m_wasFinished = true; };
+ bool wasFinished() const { return m_wasFinished; }
+private:
+ bool m_wasFinished;
+};
+
+class BaseCountVisitor : public HierarchyVisitor
+{
+public:
+ BaseCountVisitor() : m_count(0) {}
+
+ void visit(SbkBaseWrapperType*)
+ {
+ m_count++;
+ }
+
+ int count() const { return m_count; }
+private:
+ int m_count;
+};
+
+class BaseAccumulatorVisitor : public HierarchyVisitor
+{
+public:
+ BaseAccumulatorVisitor() {}
+
+ void visit(SbkBaseWrapperType* node)
+ {
+ m_bases.push_back(node);
+ }
+
+ std::list<SbkBaseWrapperType*> bases() const { return m_bases; }
+private:
+ std::list<SbkBaseWrapperType*> m_bases;
+};
+
+class GetIndexVisitor : public HierarchyVisitor
+{
+public:
+ GetIndexVisitor(PyTypeObject* desiredType) : m_index(-1), m_desiredType(desiredType) {}
+ virtual void visit(SbkBaseWrapperType* node)
+ {
+ m_index++;
+ if (PyType_IsSubtype(reinterpret_cast<PyTypeObject*>(node), m_desiredType))
+ finish();
+ }
+ int index() const { return m_index; }
+
+private:
+ int m_index;
+ PyTypeObject* m_desiredType;
+};
+
+/// \internal Internal function used to walk on classes inheritance trees.
+/**
+* Walk on class hierarchy using a DFS algorithm.
+* For each pure Shiboken type found, HiearchyVisitor::visit is called and the algorithm consider
+* all children of this type as visited.
+*/
+void walkThroughClassHierarchy(PyTypeObject* currentType, HierarchyVisitor* visitor);
+
+inline int getTypeIndexOnHierarchy(PyTypeObject* baseType, PyTypeObject* desiredType)
+{
+ GetIndexVisitor visitor(desiredType);
+ walkThroughClassHierarchy(baseType, &visitor);
+ return visitor.index();
+}
+
+inline int getNumberOfCppBaseClasses(PyTypeObject* baseType)
+{
+ BaseCountVisitor visitor;
+ walkThroughClassHierarchy(baseType, &visitor);
+ return visitor.count();
+}
+
+inline std::list<SbkBaseWrapperType*> getCppBaseClasses(PyTypeObject* baseType)
+{
+ BaseAccumulatorVisitor visitor;
+ walkThroughClassHierarchy(baseType, &visitor);
+ return visitor.bases();
+}
+
+}
+
+#endif
diff --git a/libshiboken/bindingmanager.cpp b/libshiboken/bindingmanager.cpp
index 5d9cb484e..26e146031 100644
--- a/libshiboken/bindingmanager.cpp
+++ b/libshiboken/bindingmanager.cpp
@@ -33,8 +33,10 @@
*/
#include "basewrapper.h"
+#include "basewrapper_p.h"
#include "bindingmanager.h"
#include "google/dense_hash_map"
+#include <cstddef>
namespace Shiboken
{
@@ -85,10 +87,9 @@ bool BindingManager::hasWrapper(const void* cptr)
{
return m_d->wrapperMapper.count(cptr);
}
-void BindingManager::registerWrapper(SbkBaseWrapper* pyobj)
+void BindingManager::registerWrapper(SbkBaseWrapper* pyobj, void* cptr)
{
SbkBaseWrapperType* instanceType = reinterpret_cast<SbkBaseWrapperType*>(pyobj->ob_type);
- void* cptr = pyobj->cptr;
if (instanceType->mi_init && !instanceType->mi_offsets)
instanceType->mi_offsets = instanceType->mi_init(cptr);
@@ -105,14 +106,20 @@ void BindingManager::registerWrapper(SbkBaseWrapper* pyobj)
void BindingManager::releaseWrapper(PyObject* wrapper)
{
- void* cptr = SbkBaseWrapper_cptr(wrapper);
- m_d->releaseWrapper(cptr);
- if (((SbkBaseWrapperType*) wrapper->ob_type)->mi_offsets) {
- int* offset = ((SbkBaseWrapperType*) wrapper->ob_type)->mi_offsets;
- while (*offset != -1) {
- if (*offset > 0)
- m_d->releaseWrapper((void*) ((size_t) cptr + (*offset)));
- offset++;
+ SbkBaseWrapperType* sbkType = reinterpret_cast<SbkBaseWrapperType*>(wrapper->ob_type);
+ int numBases = sbkType->is_multicpp ? getNumberOfCppBaseClasses(wrapper->ob_type) : 1;
+
+ void** cptrs = reinterpret_cast<SbkBaseWrapper*>(wrapper)->cptr;
+ for (int i = 0; i < numBases; ++i) {
+ void* cptr = cptrs[i];
+ m_d->releaseWrapper(cptr);
+ if (sbkType->mi_offsets) {
+ int* offset = sbkType->mi_offsets;
+ while (*offset != -1) {
+ if (*offset > 0)
+ m_d->releaseWrapper((void*) ((std::size_t) cptr + (*offset)));
+ offset++;
+ }
}
}
}
diff --git a/libshiboken/bindingmanager.h b/libshiboken/bindingmanager.h
index ec5a936f4..150baa90a 100644
--- a/libshiboken/bindingmanager.h
+++ b/libshiboken/bindingmanager.h
@@ -50,7 +50,7 @@ public:
bool hasWrapper(const void *cptr);
- void registerWrapper(SbkBaseWrapper* pyobj);
+ void registerWrapper( Shiboken::SbkBaseWrapper* pyobj, void* cptr);
void releaseWrapper(PyObject* wrapper);
PyObject* retrieveWrapper(const void* cptr);
PyObject* getOverride(const void* cptr, const char* methodName);
diff --git a/libshiboken/conversions.h b/libshiboken/conversions.h
index 521e5f576..b1d57eb61 100644
--- a/libshiboken/conversions.h
+++ b/libshiboken/conversions.h
@@ -153,7 +153,7 @@ struct Converter<T*>
if (pyobj == Py_None)
return 0;
else if (Shiboken_TypeCheck(pyobj, T))
- return (T*) SbkBaseWrapper_cptr(pyobj);
+ return (T*) getCppPointer(pyobj, SbkType<T>());
else if (Converter<T>::isConvertible(pyobj))
return CppObjectCopier<T>::copy(Converter<T>::toCpp(pyobj));
return 0;
@@ -192,7 +192,8 @@ struct Converter<void*>
{
if (pyobj == Py_None)
return 0;
- return SbkBaseWrapper_cptr(pyobj);
+ // When someone request a void pointer, just give to him the first C++ object in the class hierarchy
+ return reinterpret_cast<SbkBaseWrapper*>(pyobj)->cptr[0];
}
};
template <> struct Converter<const void*> : Converter<void*> {};
@@ -236,7 +237,7 @@ struct ValueTypeConverter
return *cptr;
}
}
- return *reinterpret_cast<T*>(reinterpret_cast<Shiboken::SbkBaseWrapper*>(pyobj)->cptr);
+ return *reinterpret_cast<T*>(getCppPointer(pyobj, SbkType<T>()));
}
};
@@ -269,8 +270,8 @@ struct ObjectTypeConverter
return 0;
SbkBaseWrapperType* shiboType = reinterpret_cast<SbkBaseWrapperType*>(pyobj->ob_type);
if (shiboType->mi_specialcast)
- return (T*) shiboType->mi_specialcast(SbkBaseWrapper_cptr(pyobj), reinterpret_cast<SbkBaseWrapperType*>(SbkType<T>()));
- return (T*) SbkBaseWrapper_cptr(pyobj);
+ return (T*) shiboType->mi_specialcast(getCppPointer(pyobj, SbkType<T>()), reinterpret_cast<SbkBaseWrapperType*>(SbkType<T>()));
+ return (T*) getCppPointer(pyobj, SbkType<T>());
}
};
@@ -551,7 +552,7 @@ struct StdListConverter
static StdList toCpp(PyObject* pyobj)
{
if (PyObject_TypeCheck(pyobj, SbkType<StdList>()))
- return *reinterpret_cast<StdList*>(SbkBaseWrapper_cptr(pyobj));
+ return *reinterpret_cast<StdList*>(getCppPointer(pyobj, SbkType<StdList>()));
StdList result;
for (int i = 0; i < PySequence_Size(pyobj); i++) {