> From: wccppp <[EMAIL PROTECTED]> > Subject: [python-win32] question about COM again: variable type? > > [code] > ms.AddPoint([0.0, 0.0, 0.0]) # this line gives the problem > [/code] > > # Result is of type IAcadPoint > def AddPoint(self, Point=defaultNamedNotOptArg): > """Creates a Point object at a given location""" > ret = self._oleobj_.InvokeTypes(1562, LCID, 1, (9, 0), ((12, > 1),),Point) > if ret is not None: > ret = Dispatch(ret, 'AddPoint', > '{35AF3AB5-755E-4AC9-8BAF-31B532870751}', UnicodeToString=0) > return ret > Sorry for the long reply.
The type library for AutoCad 2006 says that coordinates should be passed as variants, so makepy's output is correct. But you can change the makepy-generated file to process the argument as an array of doubles instead of a variant and it will work. I'm not sure if that's because the interface will also accept a 'raw' array, or if pythoncom is magically wrapping the array in a variant. Taking from the AddPoint method of the IAcadModelSpace class that you've included: [code] ret = self._oleobj_.InvokeTypes(1562, LCID, 1, (9, 0), ((12, 1),),Point) [/code] The (12, 1) part describes the Point argument as an (Variant, Input), roughly. This should be changed to (8197, 1), which is (Array of Doubles, Input): [code] ret = self._oleobj_.InvokeTypes(1562, LCID, 1, (9, 0),((8197,1),),Point) [/code] Unfortunately, this happens all over the place -- not just the AddPoint method. It would be very tedious to go through makepy's output and make the >1500 changes. (12, 1) cannot be changed globally in there. It also happens for more than just coordinate arguments; the Select methods of SelectionSet objects have filters which are also arrays wrapped in a variant. I haven't run across any others; the code below fixes everything I've found. My solution was to change build.py (does some of makepy's work; located in %pythoninstalldir%\lib\site-packages\win32com\client\) to apply this Variant -> Array change for me when processing the type library. The line numbers I reference are from pywin32 2.07; I tried to include enough context to find the right parts of build.py in case yours is different. My understanding of COM is not good, and these changes to build.py don't seem suitably robust. It does a small check to see if it's processing an Autocad library, but I suggest restoring build.py to its original state after processing your Autocad type libraries. You'll lose these fixes for dynamic dispatch in that case. I would be grateful if somebody could point out any red flags or suggest a better approach. Near the top of build.py (~line 52): [code] NoTranslateMap = {} for v in NoTranslateTypes: NoTranslateMap[v] = None #My addition starts here AutocadTranslateMap = { ('alignpoint','anglevertex','arccenter','arcpoint','axisdir', 'axispoint','basepoint','boundry','center','centerpoint', 'chordpoint','controlpoint','controlpoints','coordinates', 'definitionpoint','dimlinelocation','direction', 'directionvector','endpoint','endtangent','extline1point', 'extline1startpoint','extline2endpoint','extline2point', 'extline2startpoint','farchordpoint','firstendpoint','fitpoint', 'fitpoints','frompoint','insertionpoint','inspoint','jogpoint', 'knots','knotvalues','leader1point','leader2point', 'leaderendpoint','limits','lowerleft','lowleft','majoraxis', 'normal','origin','overridecenter','overridecenterpos', 'plotorigin','point','point1','point2','point3','point4', 'pointsarray','pointslist','pointsmatrix','porigin', 'secondendpoint','secondpoint','snapbasepoint','startpoint', 'starttangent','target','targetpoint','textalignmentpoint', 'textpoint','textpos','textposition','topoint', 'transformationmatrix','upperright','vertex','vertexlist', 'vertices','verticeslist','weights','wpt','wpt1','wpt2', 'xaxispoint','xline1point','xline2point','xvector', 'yaxispoint','yvector'): 8197, ('filtertype',): 8193, ('filterdata',): 8204 } #My addition ends here class MapEntry: "Simple holder for named attibutes - items in a map." def __init__(self, desc_or_id, names=None, doc=None, resultCLSID=pythoncom.IID_NULL, resultDoc = None, hidden=0): [/code] Then, in the _AddFunc_ method of class DispatchItem (~line 175): Note that the code below has been stripped of its indentation to hopefully make it more readable in email. Indentation within the posted code is correct, but the entire code block needs to be indented to match its context in build.py. [code] fdesc.rettype = typerepr, flag, defval, resultCLSID # Translate any Alias or Enums in argument list. argList = [] #Changes begin here; #for argDesc in fdesc.args: for index, argDesc in enumerate(fdesc.args): typerepr, flag, defval = argDesc #Catch only if reasonably sure this is Autocad if self.python_name[:5] == 'IAcad': #Catch (VT_VARIANT, FIN) and (VT_VARIANT, FIN|FOPT) #Outputs seem to translate into tuples just fine already if typerepr == 12 and (flag == 1 or flag == 17): if len(fdesc.args) == len(names): #???Properties??? replace = [key for key in AutocadTranslateMap.keys() \ if names[index].lower() in key] if replace: typerepr = AutocadTranslateMap[replace[0]] else: #names[0] is method name; names[1:] is arg names replace = [key for key in AutocadTranslateMap.keys() \ if names[index+1].lower() in key] if replace: typerepr = AutocadTranslateMap[replace[0]] #Changes end here; arg_type, arg_clsid, arg_doc = _ResolveType(typerepr, typeinfo) argDesc = arg_type, flag, defval, arg_clsid # sys.stderr.write("%s\n" % (argDesc[0],)) argList.append(argDesc) fdesc.args = tuple(argList) [/code] _______________________________________________ Python-win32 mailing list Python-win32@python.org http://mail.python.org/mailman/listinfo/python-win32