5

I'm having a bit of a play with using COM objects with Python and have run into a small problem.

The COM object I am using has a method called SetCallback which takes a object, the mothod looks like this:

    [id(0x60010010)]
    void SetCallback([in] IDispatch* callbackobject);

Taken from MS OLE/COM Object viewer

Now if I create and instance of my COM app in python everything is fine until I try and pass an instance of a object to this method.

callback = Callback()
mycomobject.SetCallback(callback)

class Callback():
    def SetStatusText(self,status):
        print status

The error I get in the python window is: TypeError: The Python instance can not be converted to a COM object

When doing the same thing in C# I used to make my class def look like this:

[ComVisible(True)]
public class Callback 
{
   //some methods here
}

and the method call is the same as Python version.

Is there something like this I have to do in Python in order to use an instance of a object as a callback for a COM object.

1
  • interesting problem. The com system works great with standard python datatypes (int, strings, unicode...). Would it be possible to create a workaround, like make a monitoring class that could mimick the SetCallback function? Commented Apr 6, 2011 at 17:02

3 Answers 3

3

Worked it out! Just needed to make my own COM server and register it, then create the object via Dispatch:

class Callback():
    _public_methods_ = ['SetStatusText']
    _reg_progid_ = "mycomobject.PythonCallback"
    _reg_clsid_ = "{14EF8D30-8B00-4B14-8891-36B8EF6D51FD}"
    def SetStatusText(self,status):
        print status

if __name__ == "__main__":
    print "Registering COM server..."
    import win32com.server.register
    win32com.server.register.UseCommandLine(Callback)
    main()

in main()

callback = Dispatch("mycomobject.PythonCallback")
#callback.SetStatusText("Hello World")
mycomobject.SetCallback(callback)
Sign up to request clarification or add additional context in comments.

Comments

0

AFAIK the object will need to be COM compliant. I wouldn't know out of the box to be honest, but we have a somewhat similar situation (in a software from a vendor) that is addressed on their end by using ActiveState's ActivePython.

Works alright both ways, with a dispatcher to automatically wrap COM compliant objects for python access, and the other way around. If you don't have licensing and/or financial constraints it might be worth giving it a look.

Looking forward to the replies if someone can crack it open without any additional libraries.

Comments

0

If you want to avoid registration, you can simply wrap your Python object via win32com.server.util.wrap():

import win32com.server.util

callback = Callback()
mycomobject.SetCallback(win32com.server.util.wrap(callback))

class Callback():
    _public_methods_ = ['SetStatusText']
    def SetStatusText(self,status):
        print status

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.