问题
I'm attempting to use PyQt to talk to an ActiveX COM object in Python. This method works in Python:
myobj.dynamicCall('SetAbsMovePos(int, double)', [0, 10])
However, I can't send arguments by reference. From the docs, the method I wish to call is:
int GetNumHWUnits (int lHWType, int& plNumUnits)
and the basic example code is:
QVariantList params = ...
int result = object->dynamicCall("GetNumHWUnits(int, int&)", params).toInt();
I presume the equivalent code in Python, using ctypes, should be:
num = ctypes.c_int()
myobj.dynamicCall('GetNumHWUnits(int, int&)', [6, ctypes.byref(num)])
but num
is never updated.
What's the equivalent code or workaround in Python, and how can I send and later read an argument of type int&
using Python?
回答1:
You could try to pass a list with just one element:
def funct(a):
a[0] = 4
b = [3]
funct(b)
print b[0]
Output: 4
回答2:
QVariant
is involved:
QVariant dynamicCall(const char *, QList<QVariant> & /GetWrapper/);
%MethodCode
Py_BEGIN_ALLOW_THREADS
sipRes = new QVariant(sipCpp->dynamicCall(a0, *a1));
Py_END_ALLOW_THREADS
// Update the input list with the (possibly) new values.
for (SIP_SSIZE_T i = 0; i < PyList_GET_SIZE(a1Wrapper); ++i)
{
QVariant *v = new QVariant(a1->at(i));
PyObject *v_obj = sipConvertFromNewType(v, sipType_QVariant, NULL);
In a nutshell, QVariant
is a wrapper to pass a value by reference.
Which means by passing c_int
, you have wrapped the value twice. Try to pass a real QVariant
instead of c_int
as second argument. Without this, the automatic type coercion in PyQt would take your c_int
, wrap its value in a QVariant
, call dynamicCall
. During the call, the new QVariant
is updated but there is no connection to the original c_int
so your instance won't change.
This should work:
num = QVariant(0)
myobj.dynamicCall('GetNumHWUnits(int, int&)', [6, num])
print repr(num.value())
回答3:
Got the solution from the PyQt mailing list. A reference to the list of arguments is needed, as only that list is updated; the original QVariant objects never are. Seems fairly obvious in retrospect!
typ = QVariant(6)
num = QVariant(0)
args_list = [typ, num]
self.dynamicCall('GetNumHWUnits(int, int&)', args_list)
print 'Num of HW units =', args_list[1].toInt()[0]
A full code example is shown in this post.
来源:https://stackoverflow.com/questions/25379146/passing-integer-by-reference-in-python