If you’re prepared to consider another approach, comtypes
(https://pypi.python.org/pypi/comtypes) can generate module definitions from
TLB files. Comtypes supports passing by reference via the underlying ctypes
FFI.
Andrew.
-------------------------> "These thoughts are mine alone!" <---------
Andrew MacIntyre Operations, Services and Technologies Branch
tel: +61 2 6219 5356 Communications Infrastructure Division
Australian Communications & Media Authority
email: [email protected]<mailto:[email protected]>
http://www.acma.gov.au/
From: python-win32
[mailto:[email protected]] On Behalf
Of Peter Enenkel
Sent: Tuesday, 21 February 2017 6:46 AM
To: Tim Roberts
Cc: [email protected]
Subject: Re: [python-win32] passing array by reference (3)
Hello Tim,
I concur that the array SHOULD be a return value (at the very least in Python).
Unfortunately it isn't. Definitely not with late binding and I think not with
early binding. The function does expect a parameter of the described type and
does not return anything.
In my opinion it would theoretically be possible to process an argument by
reference in Python, of cause it would have to be a mutable object. Which, as
you mentioned, tuples are not, so it would have to be restricted to lists or
some specialized transport object. Admittedly, any such solution would not be
particularly pythonic. I thought that the pythoncom.VARIANT class is such a
transport object. But I could not get it to work.
I suspect that you are correct that the interface might not be declared
properly on the serverside. On the other hand similar problems with passing
arrays by reference seem to have cropped up with other COM servers also.
I have access to the official Catia V5 automation IDL documentation (which is
reasonably complete) as well as the .tlb files. But I do not know what I could
do with the later.
Unfortunately Catia has deemed it necessary to split the COM server into
several (more that two dozen) files which doesn't exactly help with early
binding and identifying the required interfaces. That is probably one of the
reasons I could not get it to work with early binding. An other difficulty with
that is, that (interface) inheritance is used, i.e. both PartDocument and
ProductDocument both inherit from Document but each has additional attributes.
Functions always seem to return the base type which then would require some
kind of cast.
I have managed to implement a workaround in the manner that Andreas Holtz
suggested. That is, using win32com to instruct Catia to execute a VBScript
function which calls GetComponents with an ByRef argument and then returns it
as a return value, which in turn is passed back to python. Not a particularly
elegant solution, but it works! So the pressure to find a "native" solution
isn't quite as high as before. Nevertheless I'm still interested in a way to do
it "right". If you have any ideas in that direction I'd appreciate hearing them.
best regards
Peter
2017-02-20 19:07 GMT+01:00 Tim Roberts <[email protected]<mailto:[email protected]>>:
Peter Enenkel wrote:
>
> I'm trying to read some data from CATIA v5 (which is an older CAD
> application) via its COM server. Overall it works rather well, even if
> I'm fairly new to COM communication.
>
> Nevertheless I have run into a problem: One specific function
> *GetComponents * is supposed to return its results via an array passed
> by reference. As far as I can tell it is exactly the same problem as
> in
> (1)https://mail.python.org/pipermail/python-win32/2002-November/000562.html
> and
> (2)https://mail.python.org/pipermail/python-win32/2014-July/013234.html
> unfortunately there doesn't appear to be a solution as of yet.
>
> The python call looks something like this
> a = list(range(0,12))
> b = catapp.ActiveProduct.Position.GetComponents(a)
> print(a) # outputs (0,1,2,3,4,5,6,7,8,9,10,11) instead of the actual
> values
Usually, in this kind of situation, the array would be an output parameter:
b, a = catapp.ActiveProduct.Position.GetComponents()
Remember that Python doesn't actually do pass-by-reference in the way
you are used to. In your code above, you aren't really passing "a".
What you're passing is the list that "a" is bound to. The Python COM
code converts that into whatever type the function wants. If that array
gets changed, it doesn't change the list. It can't, because that
parameter might actually have been a tuple, which can't be modified, and
there is no way for the function to change the binding of "a". That's
why the COM stuff usually returns the changed parameter, so you can
change your binding.
Do you have the actual function signature in C++ or IDL form? If they
haven't declared it properly, PythonCOM might not be able to determine
that this is an output parameter.
--
Tim Roberts, [email protected]<mailto:[email protected]>
Providenza & Boekelheide, Inc.
_______________________________________________
python-win32 mailing list
[email protected]<mailto:[email protected]>
https://mail.python.org/mailman/listinfo/python-win32
NOTICE: This email message is for the sole use of the intended recipient(s)
and may contain confidential and privileged information. Any unauthorized
review, use, disclosure or distribution is prohibited. If you are not the
intended recipient, please contact the sender by reply email and destroy all
copies of the original message.
_______________________________________________
python-win32 mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-win32