Nathan W
Nathan W

Reputation: 55472

Python instance to COM Object

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.

Upvotes: 5

Views: 5972

Answers (3)

David Gausmann
David Gausmann

Reputation: 1718

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

Upvotes: 0

Nathan W
Nathan W

Reputation: 55472

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)

Upvotes: 3

user349594
user349594

Reputation:

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.

Upvotes: 0

Related Questions