Skip to content

Commit 2b4cace

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

File tree

3 files changed

+42
-25
lines changed

3 files changed

+42
-25
lines changed

src/PythonQtConversion.cpp

Lines changed: 10 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 = ConversionUtils::getPtrAndUpdateCppObject<QByteArray>(alreadyAllocatedCPPObject, frame, 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 = ConversionUtils::getPtrAndUpdateCppObject<QString>(alreadyAllocatedCPPObject, frame, 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 = ConversionUtils::getPtrAndUpdateCppObject<QStringList>(alreadyAllocatedCPPObject, frame, 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,26 @@ 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 ConversionUtils::getPtrAndUpdateCppViewObject<QString, QStringView>(alreadyAllocatedCPPObject, frame,
664+
str);
672665
} else {
673666
return nullptr;
674667
}
675668
} else if (info.typeId == anyStringViewTypeId) {
676669
// Handle QAnyStringView, which needs a reference to a persistent QString
677670
QString str = PyObjGetString(obj, strict, ok);
678671
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;
672+
return ConversionUtils::getPtrAndUpdateCppViewObject<QString, QAnyStringView>(alreadyAllocatedCPPObject,
673+
frame, str);
685674
} else {
686675
return nullptr;
687676
}
688677
} else if (info.typeId == byteArrayViewTypeId) {
689678
// Handle QByteArrayView, which needs a reference to a persistent QByteArray
690679
QByteArray ba = PyObjGetBytesAllowString(obj, strict, ok);
691680
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;
681+
return ConversionUtils::getPtrAndUpdateCppViewObject<QByteArray, QByteArrayView>(alreadyAllocatedCPPObject,
682+
frame, ba);
698683
} else {
699684
return nullptr;
700685
}

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: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,4 +133,35 @@ class PythonQtArgumentFrame
133133
static PythonQtArgumentFrame* _freeListHead;
134134
};
135135

136+
namespace ConversionUtils {
137+
template<typename Class>
138+
void* getPtrAndUpdateCppObject(void* alreadyAllocatedPtr, PythonQtArgumentFrame* store, const Class& value)
139+
{
140+
if (alreadyAllocatedPtr) {
141+
*reinterpret_cast<Class*>(alreadyAllocatedPtr) = value;
142+
return alreadyAllocatedPtr;
143+
} else {
144+
QVariant* item = store->nextVariantPtr();
145+
*item = QVariant(value);
146+
return const_cast<void*>(item->constData());
147+
}
148+
}
149+
150+
template<typename Class, typename ViewClass>
151+
void* getPtrAndUpdateCppViewObject(void* alreadyAllocatedPtr, PythonQtArgumentFrame* store, const Class& value)
152+
{
153+
QVariant* itemStore = store->nextVariantPtr();
154+
*itemStore = QVariant(value);
155+
if (alreadyAllocatedPtr) {
156+
*reinterpret_cast<ViewClass*>(alreadyAllocatedPtr) =
157+
ViewClass(*reinterpret_cast<const Class*>(itemStore->constData()));
158+
return alreadyAllocatedPtr;
159+
} else {
160+
QVariant* item = store->nextVariantPtr();
161+
*item = QVariant::fromValue(ViewClass(*reinterpret_cast<const Class*>(itemStore->constData())));
162+
return const_cast<void*>(item->constData());
163+
}
164+
}
165+
}
166+
136167
#endif

0 commit comments

Comments
 (0)