[python-win32] Python wn32com : How to give byRef parameters in object method and then get updated values

Pascal pasc.marchand at free.fr
Sat Mar 7 14:50:05 CET 2015


Hi,

Sorry Greg, as I was the only recipient of the message, I didn't take 
care to dispatch email to full python-win32 list.

I work a few since my last email and yes, I have several questions and 
comments about use of win32com through SolidWorks API.

1-/ I tried makepy and the result was the same, but with google and 
patience I found a way to make my functions work.

There is for me some suprising behaviour :

e.g. :

Open a doc works as :

     def openDoc(self, path, docType):
         model, errors, warnings = sw.OpenDoc6(model_path, cst(docType), 
swconst.constants.swOpenDocOptions_Silent, '', pythoncom.Missing, 
pythoncom.Missing)
         model.Visible = True
         return model

while getting parameters function get5 works as :

     def params(self,ipart,cfg):
         ext = ipart.Extension
         custPropMgr = ext.CustomPropertyManager(cfg)
         pNames = tuple(custPropMgr.GetNames)
         pValues = []
         res=0
         for item in pNames:
             valOut = VARIANT(pythoncom.VT_BYREF | pythoncom.VT_BSTR,'F')
             resolvedValOut = VARIANT(pythoncom.VT_BYREF | 
pythoncom.VT_BSTR,'R')
             wasResolved = VARIANT(pythoncom.VT_BYREF | 
pythoncom.VT_BOOL, 0)
             res = custPropMgr.Get5(item, False, resolvedValOut, valOut, 
wasResolved )
             v_wR  = wasResolved.value
             v_wasResolved = valOut.value
             v_valOut = v_wR
             v_resolvedValOut = resolvedValOut.value
             pValues.append([v_valOut, v_resolvedValOut, v_wasResolved])
         return pValues

In first case only byRef parameters are needed and then they are 
returned as triple with the normal result in usual language (model)
In second case, if you don't give a correct typed parameter, it raise an 
error : type mismatch or missing (in case of pythoncom.missing)
Moreover, it don't return as I hoped : normal_result, byref1, byref2, 
byref3 = custPropMgr.Get5(...) but only normal_result = 
custPropMgr.Get5(...)
and byref results returned in defined variables (made with VARIANT)
Note : returned parameters are not in the right order (seems to be in 
reverse order)
           not really important, except in loop, because types are not 
always the same, so you must init vars in the loop!

2-/ Note : this also works without making a makepy module (very 
interesting for future use because nothing special to do)

We have a kind of common experience, because my first use of Python and 
solidworks (not together) happens when I worked with MSC Marc/autoforge 
Non-linear finite element softwares.

Thanks for your support and your french encouragement.
______________________________________________________________
Greg wrote:

I only use SolidWorks occasionally, and I have never tried to use its 
API. But, it's on my computer and I knew what to look for based on my 
prior experience with a finite element pre/post processor called Femap, 
so I was able to help.

If you have further questions, it is best to send them to the discussion 
list rather than directly to me, even if I eventually answer them. 
Everything sent to the list is archived, so other people with similar 
problems may be able find answers in the archives. That's why I sent my 
answer to the list, too.

Bonne chance, et bon courage.

- Greg

------------------
Gregory W. Antal
Senior Technical Advisor
ATA Engineering, Inc.
13290 Evening Creek Drive South, Suite 250
San Diego, CA 92128
www.ata-e.com

greg.antal at ata-e.com
858-480-2072 (Phone)
858-792-8932 (Fax)
------------------

Pascal wrote on 3/6/2015 12:20 AM:
Hi,

Thank you so much Greg for your quick reply.
I will try it asap.
I saw several times references to makepy but it was usually confuse for 
me and I didn't understand really what is behind it.
Your explanation is very clear and I understand better its utility.

Maybe, I'm a bit curious, but you seems to know Solidworks, do you use 
Python with it ?

Thanks again and have a good day.

Le 06/03/2015 01:47, Greg Antal a écrit :
> Pascal wrote on 3/5/2015 2:22 PM:
>> Hello,
>>
>> I'm not an expert, I just want to experiment python with SolidWorks
>> I'm trying to use its DLL with some success, but unfortunately, with 
>> some errors :
>> File "<COMObject <unknown>>", line 2, in Get5
>> com_error: (-2147352571, 'Type mismatch', None, 5)
>>
>> I'm not sure about error comment, it's a translation because my 
>> python is in french language.
>>
>> Here is a simplified extract of code :
>>
>> app = win32com.client.Dispatch('Sldworks.Application')
>> part = app.ActiveDoc
>>
>> docext = part.Extension
>> custPropMgr = docext.CustomPropertyManager('ma_config')
>> pNames = tuple(custPropMgr.GetNames) # return array of strings
>>
>> for item in pNames:
>>       print(item) # string is well printed
>>       var1=''
>>       var2=''
>>       var3=False
>>       custPropMgr.Get5(item, False, var1, var2, var3) <== error 
>> happens here
>>
>> I tried several things but I didn't reach to pass correctly the 
>> parameters to the Get5 method.
>> I think the problem is with the ByRef parameters, because I already 
>> used many method with ByVal parameters and it works rather fine.
>>
>> I tried : var1, var2, var3 = custPropMgr.Get5(item, False)  as 
>> suggested somewhere but it didn't works
>>
>> this method is described as below in the solidworks API help:
>>
>> Visual Basic (Declaration) 	
>> Function Get5( _
>>     ByVal/FieldName  <http://help.solidworks.com/2015/english/api/sldworksapi/solidworks.interop.sldworks%7Esolidworks.interop.sldworks.icustompropertymanager%7Eget5.html#>/  As System.String, _
>>     ByVal/UseCached  <http://help.solidworks.com/2015/english/api/sldworksapi/solidworks.interop.sldworks%7Esolidworks.interop.sldworks.icustompropertymanager%7Eget5.html#>/  As System.Boolean, _
>>     ByRef/ValOut  <http://help.solidworks.com/2015/english/api/sldworksapi/solidworks.interop.sldworks%7Esolidworks.interop.sldworks.icustompropertymanager%7Eget5.html#>/  As System.String, _
>>     ByRef/ResolvedValOut  <http://help.solidworks.com/2015/english/api/sldworksapi/solidworks.interop.sldworks%7Esolidworks.interop.sldworks.icustompropertymanager%7Eget5.html#>/  As System.String, _
>>     ByRef/WasResolved  <http://help.solidworks.com/2015/english/api/sldworksapi/solidworks.interop.sldworks%7Esolidworks.interop.sldworks.icustompropertymanager%7Eget5.html#>/  As System.Boolean _
>> ) As System.Integer
>>
>> Visual Basic (Usage) 	
>> Dim instance AsICustomPropertyManager  <http://help.solidworks.com/2015/english/api/sldworksapi/SolidWorks.Interop.sldworks%7ESolidWorks.Interop.sldworks.ICustomPropertyManager.html>
>> Dim FieldName As System.String
>> Dim UseCached As System.Boolean
>> Dim ValOut As System.String
>> Dim ResolvedValOut As System.String
>> Dim WasResolved As System.Boolean
>> Dim value As System.Integer
>>   
>> value = instance.Get5(FieldName, UseCached, ValOut, ResolvedValOut, WasResolved)
>>
>>
>
> I'm not much of an expert either, but I also use an API with many 
> ByRef parameters in its method calls. The way I solved the problem was 
> to use "early binding" of the COM objects.
>
> To do that, you must first find the Type Library for your API. For 
> SolidWorks, this may be "sldworks.tlb", although I can't really be 
> sure. I see 20 "tlb" files in my [/SolidWorks_path/]\SolidWorks 
> folder, and I have no idea which one you might need, or even if you 
> need all of them. I would start with "sldworks.tlb".
>
> Next, from that type library, you create a Python file that you can 
> import into your code. You do that with the "makepy" utility that 
> comes with the Python COM package.
> 1. Open a command window in the folder where you keep the Python code 
> you're developing.
> 2. Enter the command
> [/Python_path/]\Lib\site-packages\win32com\client\makepy.py -v -o 
> PySldworks.py [/SolidWorks_path/]\SolidWorks\sldworks.tlb
> This will create a file called PySldworks.py (you can name it whatever 
> you  want, of course). Now you can just add "Import PySldworks" to all 
> the Import statements you already use.
>
> Instead of
> app = win32com.client.Dispatch('Sldworks.Application')
>
> you have something like
> app = PySldworks.SldWorks
>
> Now those calls that return data using ByRef parameters should work 
> with the Python-like form you tried because PySldworks.py has already 
> defined it:
> var1, var2, var3 = custPropMgr.Get5(item, False)
>
> If that method has a return code, it will appear before the ByRef 
> parameters:
> rc, var1, var2, var3 = custPropMgr.Get5(item, False)
>
> If that doesn't work, you can look in PySldworks.py to understand 
> exactly what it thinks it should do with that method; it is, after 
> all, just another Python file.
>
> If there is another way to solve this problem, I don't know what it 
> is. One of the real experts who monitor this list will have to help 
> you with that.
>
> - Greg Antal
>
> ------------------
> Gregory W. Antal
> Senior Technical Advisor
> ATA Engineering, Inc.
> 13290 Evening Creek Drive South, Suite 250
> San Diego, CA 92128
> www.ata-e.com
>
> greg.antal at ata-e.com
> 858-480-2072 (Phone)
> 858-792-8932 (Fax)
> ------------------




---
L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel antivirus Avast.
http://www.avast.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-win32/attachments/20150307/f987fdcb/attachment.html>


More information about the python-win32 mailing list