Skip to content

Commit d147d54

Browse files
JanPlathusiems
authored andcommitted
Fix invalid handling of alreadyAllocatedCPPObject in PythonQtConv::ConvertPythonToQt
1 parent 68a5d48 commit d147d54

File tree

3 files changed

+37
-25
lines changed

3 files changed

+37
-25
lines changed

src/PythonQtConversion.cpp

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -592,24 +592,21 @@ void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i
592592
{
593593
QByteArray bytes = PyObjGetBytesAllowString(obj, strict, ok);
594594
if (ok) {
595-
PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(alreadyAllocatedCPPObject, frame, QVariant(bytes), ptr);
596-
ptr = (void*)((QVariant*)ptr)->constData();
595+
ptr = frame->establishPersistentPtr<QByteArray>(alreadyAllocatedCPPObject, bytes);
597596
}
598597
} break;
599598
case QMetaType::QString:
600599
{
601600
QString str = PyObjGetString(obj, strict, ok);
602601
if (ok) {
603-
PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(alreadyAllocatedCPPObject, frame, QVariant(str), ptr);
604-
ptr = (void*)((QVariant*)ptr)->constData();
602+
ptr = frame->establishPersistentPtr<QString>(alreadyAllocatedCPPObject, str);
605603
}
606604
} break;
607605
case QMetaType::QStringList:
608606
{
609607
QStringList l = PyObjToStringList(obj, strict, ok);
610608
if (ok) {
611-
PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(alreadyAllocatedCPPObject, frame, QVariant(l), ptr);
612-
ptr = (void*)((QVariant*)ptr)->constData();
609+
ptr = frame->establishPersistentPtr<QStringList>(alreadyAllocatedCPPObject, l);
613610
}
614611
} break;
615612

@@ -649,7 +646,7 @@ void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i
649646
QString str = PyObjGetString(obj, strict, ok);
650647
if (ok) {
651648
void* ptr2 = nullptr;
652-
PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(nullptr, frame, QVariant(str), ptr2);
649+
PythonQtArgumentFrame_ADD_VARIANT_VALUE(frame, QVariant(str), ptr2);
653650
PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(alreadyAllocatedCPPObject, frame,
654651
QVariant::fromValue(QStringRef((const QString*)((QVariant*)ptr2)->constData())), ptr);
655652
ptr = (void*)((QVariant*)ptr)->constData();
@@ -663,38 +660,23 @@ void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i
663660
// Handle QStringView, which needs a reference to a persistent QString
664661
QString str = PyObjGetString(obj, strict, ok);
665662
if (ok) {
666-
void* ptr2 = nullptr;
667-
PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(nullptr, frame, QVariant(str), ptr2);
668-
PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(alreadyAllocatedCPPObject, frame,
669-
QVariant::fromValue(QStringView(*((const QString*)((QVariant*)ptr2)->constData()))), ptr);
670-
ptr = (void*)((QVariant*)ptr)->constData();
671-
return ptr;
663+
return frame->establishPersistentViewPtr<QString, QStringView>(alreadyAllocatedCPPObject, str);
672664
} else {
673665
return nullptr;
674666
}
675667
} else if (info.typeId == anyStringViewTypeId) {
676668
// Handle QAnyStringView, which needs a reference to a persistent QString
677669
QString str = PyObjGetString(obj, strict, ok);
678670
if (ok) {
679-
void* ptr2 = nullptr;
680-
PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(nullptr, frame, QVariant(str), ptr2);
681-
PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(alreadyAllocatedCPPObject, frame,
682-
QVariant::fromValue(QAnyStringView(*((const QString*)((QVariant*)ptr2)->constData()))), ptr);
683-
ptr = (void*)((QVariant*)ptr)->constData();
684-
return ptr;
671+
return frame->establishPersistentViewPtr<QString, QAnyStringView>(alreadyAllocatedCPPObject, str);
685672
} else {
686673
return nullptr;
687674
}
688675
} else if (info.typeId == byteArrayViewTypeId) {
689676
// Handle QByteArrayView, which needs a reference to a persistent QByteArray
690677
QByteArray ba = PyObjGetBytesAllowString(obj, strict, ok);
691678
if (ok) {
692-
void* ptr2 = nullptr;
693-
PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(nullptr, frame, QVariant(ba), ptr2);
694-
PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(alreadyAllocatedCPPObject, frame,
695-
QVariant::fromValue(QByteArrayView(*((const QByteArray*)((QVariant*)ptr2)->constData()))), ptr);
696-
ptr = (void*)((QVariant*)ptr)->constData();
697-
return ptr;
679+
return frame->establishPersistentViewPtr<QByteArray, QByteArrayView>(alreadyAllocatedCPPObject, ba);
698680
} else {
699681
return nullptr;
700682
}

src/PythonQtConversion.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ class PYTHONQT_EXPORT PythonQtConv
122122
static PyObject* ConvertQtValueToPython(const PythonQtMethodInfo::ParameterInfo& info, const void* data);
123123

124124
//! convert python object to Qt (according to the given parameter) and if the conversion should be strict (classInfo is currently not used anymore)
125+
//! If an alreadyAllocatedCPPObject is used it must have the same type as given by info.typeId
125126
static void* ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& info, PyObject* obj, bool strict,
126127
PythonQtClassInfo* classInfo, void* alreadyAllocatedCPPObject, PythonQtArgumentFrame* frame = nullptr);
127128

src/PythonQtMisc.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,35 @@ class PythonQtArgumentFrame
121121
//! Get next pointer to a POD.
122122
quint64* nextPODPtr();
123123

124+
template<typename Class>
125+
void* establishPersistentPtr(void* alreadyAllocatedPtr, const Class& value)
126+
{
127+
if (alreadyAllocatedPtr) {
128+
*reinterpret_cast<Class*>(alreadyAllocatedPtr) = value;
129+
return alreadyAllocatedPtr;
130+
} else {
131+
QVariant* item = nextVariantPtr();
132+
*item = QVariant(value);
133+
return const_cast<void*>(item->constData());
134+
}
135+
}
136+
137+
template<typename Class, typename ViewClass>
138+
void* establishPersistentViewPtr(void* alreadyAllocatedPtr, const Class& value)
139+
{
140+
QVariant* itemStore = nextVariantPtr();
141+
*itemStore = QVariant(value);
142+
if (alreadyAllocatedPtr) {
143+
*reinterpret_cast<ViewClass*>(alreadyAllocatedPtr) =
144+
ViewClass(*reinterpret_cast<const Class*>(itemStore->constData()));
145+
return alreadyAllocatedPtr;
146+
} else {
147+
QVariant* item = nextVariantPtr();
148+
*item = QVariant::fromValue(ViewClass(*reinterpret_cast<const Class*>(itemStore->constData())));
149+
return const_cast<void*>(item->constData());
150+
}
151+
}
152+
124153
private:
125154
PythonQtArgumentFrame();
126155
~PythonQtArgumentFrame();

0 commit comments

Comments
 (0)