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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.