Hi all, I have a few questions about passing parameters to methods on a component built in Visual FoxPro 7. I'm new to the list, and no COM (or win32) expert -- I've tried to do my homework, but if I've missed something, pointers to previous threads or documentation would be greatly appreciated.
Some background: I am basically using PythonCOM as the first step in porting the functions provided by this component to a Unix environment. I am running Python 2.6 for Windows with the win32com and related packages in Wine under Ubuntu. The component basically takes the form of a single FoxPro class in a DLL. Instances of this class have members that are instances of various other classes, but I don't think those classes can be directly instantiated (i.e., they are not themselves COM components exposed by the DLL). I need to be able to pass parameters to methods on these member objects. For example, suppose the component is of class C and one of its members, d, is an instance of class D; I need to be able to do something like: c = win32com.client.Dispatch("C") c.d.some_method(param1, param2) I have had some trouble getting PythonCOM to do this. My problems and questions are: 1) Regarding early binding: makepy.py doesn't seem to be able to get the right interfaces from the DLL. It doesn't seem to be able to tell, for example, that d.some_method accepts two parameters (and it assumes it accepts zero). Therefore my attempts to use early binding have been met with either COM errors (didn't pass enough arguments to c.d.some_method) or TypeErrors (the generated module expected some_method to take zero non-self arguments, but was passed two). So... 1a) Is there perhaps something I'm missing about makepy? I don't know too much about what kind of type information is in the DLL/TLB; is it possible that there is type information in there that I have to clue makepy into other than simply having it introspect the DLL in the standard way? 1b) If not, I might be able to get the DLL rebuilt with more type information. This article [1] seems to indicate that FoxPro supports both early and late binding. Does anyone have any tips for how to recompile a Foxpro component such that its interfaces will be correctly understood by makepy? 2) Regarding late binding: the way that attributes are looked up in win32com.client.dynamic.CDispatch.__getattr__ seems not to play nicely with Foxpro's way of responding to queries about the interface. I think what's happening is that __getattr__('some_method') attempts first to call Invoke with pythoncom.INVOKE_PROPERTYGET as the invocation type. As the win32com documentation indicates sometimes happens, Foxpro seems to respond to this by *calling* the method. This means that if, say, some_method returns a string, then a call like: c.d.some_method(param1, param2) blows up because __getattr__('some_method') returns a string value that results from calling some_method, rather than a reference to the method, so I get a TypeError to the effect that a string value is not callable; whereas c.d.some_method actually calls the method and returns a value, but of course I can't pass the call any parameters. I have successfully managed to pass parameters to such methods by calling Invoke() directly, with the parameters as extra positional arguments, like so: d_disp_interface = d._oleobj_.QueryInterface(pythoncom.IID_IDispatch) some_method_id = d_disp_interface.GetIDsForNames('some_method') the_value_I_seek = d_disp_interface.Invoke(some_method_id, 0, pythoncom.DISPATCH_METHOD, 1, param1, param2) This seems to work but is cumbersome; I am clearly not getting the advantages that the high-level win32com.client interface is supposed to provide. So my question here is: 2a) If I am forced to use late binding, what's the best way to deal with this issue, so that I can say things like c.d.some_method(param1, param2) without errors? Should I subclass CDispatch and override __getattr__? Or is there some way of providing CDispatch itself with some hints about which attributes of (sometimes deeply nested) members on the component are methods, and how many parameters they take? I know this is a long post, but I've had a hard time finding information about these issues, and wanted to provide as many details as I could (for my own sake as well as posterity's). Thanks for any help you all can provide! Best, Richard [1] http://msdn.microsoft.com/en-us/library/2c0y4cce(v=vs.71).aspx _______________________________________________ python-win32 mailing list python-win32@python.org http://mail.python.org/mailman/listinfo/python-win32