Skip to content

Commit c891272

Browse files
author
builder@murbella
committed
Eliminate complex typed static variables
Complex typed static variables (e.g. maps) in dll-s are to avoid. On Windows they are not initialised in time (or at all) when the dll is dynamically loaded. The current use of static QHash data members results in crash on Windows when the PythonQt.dll is loaded. See details here: http://stackoverflow.com/questions/5114683/loading-dll-not-initializing-static-c-classes
1 parent 503597b commit c891272

File tree

5 files changed

+167
-124
lines changed

5 files changed

+167
-124
lines changed

src/PythonQtClassInfo.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@
4747
#include <QMetaObject>
4848
#include <QMetaEnum>
4949

50-
QHash<QByteArray, int> PythonQtMethodInfo::_parameterTypeDict;
51-
5250
PythonQtClassInfo::PythonQtClassInfo() {
5351
_meta = NULL;
5452
_constructors = NULL;

src/PythonQtConversion.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,21 @@ PythonQtValueStorage<qint64, 128> PythonQtConv::global_valueStorage;
5151
PythonQtValueStorage<void*, 128> PythonQtConv::global_ptrStorage;
5252
PythonQtValueStorageWithCleanup<QVariant, 128> PythonQtConv::global_variantStorage;
5353

54-
QHash<int, PythonQtConvertMetaTypeToPythonCB*> PythonQtConv::_metaTypeToPythonConverters;
55-
QHash<int, PythonQtConvertPythonToMetaTypeCB*> PythonQtConv::_pythonToMetaTypeConverters;
54+
QHash<int, PythonQtConvertMetaTypeToPythonCB*>* PythonQtConv::GetMetaTypeToPythonConverters() {
55+
static QHash<int, PythonQtConvertMetaTypeToPythonCB*>* _metaTypeToPythonConverters = nullptr;
56+
if (_metaTypeToPythonConverters == nullptr) {
57+
_metaTypeToPythonConverters = new QHash<int, PythonQtConvertMetaTypeToPythonCB*>();
58+
}
59+
return _metaTypeToPythonConverters;
60+
}
61+
62+
QHash<int, PythonQtConvertPythonToMetaTypeCB*>* PythonQtConv::GetPythonToMetaTypeConverters() {
63+
static QHash<int, PythonQtConvertPythonToMetaTypeCB*>* _pythonToMetaTypeConverters = nullptr;
64+
if (_pythonToMetaTypeConverters == nullptr) {
65+
_pythonToMetaTypeConverters = new QHash<int, PythonQtConvertPythonToMetaTypeCB*>();
66+
}
67+
return _pythonToMetaTypeConverters;
68+
}
5669

5770
PyObject* PythonQtConv::GetPyBool(bool val)
5871
{
@@ -103,7 +116,7 @@ PyObject* PythonQtConv::ConvertQtValueToPython(const PythonQtMethodInfo::Paramet
103116

104117
if (info.typeId >= QMetaType::User) {
105118
// if a converter is registered, we use is:
106-
PythonQtConvertMetaTypeToPythonCB* converter = _metaTypeToPythonConverters.value(info.typeId);
119+
PythonQtConvertMetaTypeToPythonCB* converter = GetMetaTypeToPythonConverters()->value(info.typeId);
107120
if (converter) {
108121
return (*converter)(info.pointerCount==0?data:*((void**)data), info.typeId);
109122
}
@@ -668,7 +681,7 @@ void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i
668681
// We only do this for registered type > QMetaType::User for performance reasons.
669682
if (info.typeId >= QMetaType::User) {
670683
// Maybe we have a special converter that is registered for that type:
671-
PythonQtConvertPythonToMetaTypeCB* converter = _pythonToMetaTypeConverters.value(info.typeId);
684+
PythonQtConvertPythonToMetaTypeCB* converter = GetPythonToMetaTypeConverters()->value(info.typeId);
672685
if (converter) {
673686
if (!alreadyAllocatedCPPObject) {
674687
// create a new empty variant of concrete type:
@@ -1174,7 +1187,7 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type)
11741187
} else if (type >= QVariant::UserType) {
11751188
// not an instance wrapper, but there might be other converters
11761189
// Maybe we have a special converter that is registered for that type:
1177-
PythonQtConvertPythonToMetaTypeCB* converter = _pythonToMetaTypeConverters.value(type);
1190+
PythonQtConvertPythonToMetaTypeCB* converter = GetPythonToMetaTypeConverters()->value(type);
11781191
if (converter) {
11791192
// allocate a default object of the needed type:
11801193
v = QVariant(type, (const void*)NULL);

src/PythonQtConversion.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,10 +160,10 @@ class PYTHONQT_EXPORT PythonQtConv {
160160
static QString CPPObjectToString(int type, const void* data);
161161

162162
//! register a converter callback from python to cpp for given metatype
163-
static void registerPythonToMetaTypeConverter(int metaTypeId, PythonQtConvertPythonToMetaTypeCB* cb) { _pythonToMetaTypeConverters.insert(metaTypeId, cb); }
163+
static void registerPythonToMetaTypeConverter(int metaTypeId, PythonQtConvertPythonToMetaTypeCB* cb) { GetPythonToMetaTypeConverters()->insert(metaTypeId, cb); }
164164

165165
//! register a converter callback from cpp to python for given metatype
166-
static void registerMetaTypeToPythonConverter(int metaTypeId, PythonQtConvertMetaTypeToPythonCB* cb) { _metaTypeToPythonConverters.insert(metaTypeId, cb); }
166+
static void registerMetaTypeToPythonConverter(int metaTypeId, PythonQtConvertMetaTypeToPythonCB* cb) { GetMetaTypeToPythonConverters()->insert(metaTypeId, cb); }
167167

168168
//! converts the Qt parameter given in \c data, interpreting it as a \c type registered qvariant/meta type, into a Python object,
169169
static PyObject* convertQtValueToPythonInternal(int type, const void* data);
@@ -187,8 +187,8 @@ class PYTHONQT_EXPORT PythonQtConv {
187187
static PythonQtValueStorageWithCleanup<QVariant, 128> global_variantStorage;
188188

189189
protected:
190-
static QHash<int, PythonQtConvertMetaTypeToPythonCB*> _metaTypeToPythonConverters;
191-
static QHash<int, PythonQtConvertPythonToMetaTypeCB*> _pythonToMetaTypeConverters;
190+
static QHash<int, PythonQtConvertMetaTypeToPythonCB*>* GetMetaTypeToPythonConverters();
191+
static QHash<int, PythonQtConvertPythonToMetaTypeCB*>* GetPythonToMetaTypeConverters();
192192

193193
//! handle automatic conversion of some special types (QColor, QBrush, ...)
194194
static void* handlePythonToQtAutoConversion(int typeId, PyObject* obj, void* alreadyAllocatedCPPObject);

0 commit comments

Comments
 (0)