Greetings. I need a working example of implementing an event handler in
a C++ client with a python server. I broke apart the python connect
example into a client and server. (i.e. I split
C:\Python24\Lib\site-packages\win32com\demos\connect.py into client.py
and server.py in some other directory.) I then changed the guids of
server.py. I added this directory to my PYTHONPATH environment
variable. I then created an idl file to match the interface as best I
could. I compiled the idl file with visual studio's midl tool to get a
header and tlb file and I wrote a C++ client against the generated
header and tlb file.
When I register the python server and run the python client, everything
works fine. Running the C++ client gave me errors, so I tried to add
additional information from the idl file to the python server (the idl
file requires 4 uuids, but initially server.py as copied from connect.py
only had 2). The python client still works, the C++ client does not.
What I would like to know is if I need to add or change anything else in
the python server or the derived idl file, or should they work with a
C++ client as written. The typelib guid is currently defined as a
top-level _reg_clsid_ as opposed to _typelib_guid_ within the coclass
because if I set this parameter in server.py, client.py fails.
Below is a printout of the output of both clients as well as the source
of server.py and the implied idl file MyEventServer.idl:
Any help much appreciated, --Nicky Impert
>python server.py
Registered: Python.MyEventServer
>python client.py
I am being called
Sent 'Hello', but got back u'Hello_suffix'
Everything seemed to work!
still works, but when I run by C++ client, I get:
'ConnectionClient.exe': Loaded
'C:\Python24\Lib\site-packages\win32\win32trace.pyd', No symbols loaded.
pythoncom error: ERROR: server.policy could not create an instance.
Traceback (most recent call last):
File "C:\Python24\Lib\site-packages\win32com\server\policy.py", line
144, in CreateInstance
return retObj._CreateInstance_(clsid, reqIID)
File "C:\Python24\Lib\site-packages\win32com\server\policy.py", line
211, in _CreateInstance_
raise pythoncom.com_error, (hr, desc, exc, arg)
pywintypes.com_error: (-2147467262, "The object
'<server.MyConnectableServer instance at 0x01483B48>' was created, but
does not support the interface
'IConnectableServer'({F51A6858-F43E-4CF9-B603-6D15D3E8DB71}): No such
interface supported", None, None)
pythoncom error: Unexpected gateway error
Traceback (most recent call last):
(. . . -- above traceback info repeats)
pythoncom error: CPyFactory::CreateInstance failed to create instance.
(80004005)
---- server.py ----
# Implements a connectable server.
#
# Initial server code extracted from
# C:\Python24\Lib\site-packages\win32com\demos\connect.py
# then embellished in an attempt to allow a C++ client to exercise it.
import pythoncom
import win32com.server.util
import win32com.server.connect
from win32com.server.exception import Exception
# This is the IID of the Events interface both Client and Server
support.
IID__IConnectDemoEvents =
pythoncom.MakeIID("{FCA56F6D-2291-4A32-9BDE-D577D24616F1}")
IID_IConnectableServer =
pythoncom.MakeIID("{F51A6858-F43E-4CF9-B603-6D15D3E8DB71}")
# putting typelib guid up here as top-level reg_clsid because I have
# seen it done this way before, and uncommenting _typelib_guid_ causes
# the client to fail.
_reg_clsid_ = "{3593F5DE-2F61-43E9-8788-68D2D4C943D8}"
_reg_libname_ = "server Typelib"
# The server which implements
# Create a connectable class, that has a single public method
# 'DoIt', which echos to a single sink 'DoneIt'
class MyConnectableServer(win32com.server.connect.ConnectableServer):
"""Interface MyConnectableServer"""
_public_methods_ = ["DoIt"] +
win32com.server.connect.ConnectableServer._public_methods_
_reg_progid_ = "Python.MyEventServer"
# _reg_verprogid_ = "Python.MyEventServer.1"
_reg_clsid_ = "{FA5F6400-DD37-4E1D-9E2C-9BEC56C4F2AE}"
_reg_desc_ = "Python Event Server (test server -- returns
string)"
_reg_class_spec_ = "server.MyConnectableServer"
# _reg_policy_spec_ =
"win32com.servers.EventServer.SingletonPolicy"
# uncommenting these lines causes client.py to fail
# _typelib_guid_ = "{3593F5DE-2F61-43E9-8788-68D2D4C943D8}"
# _typelib_version_ = 0, 1
_connect_interfaces_ = [IID__IConnectDemoEvents]
_com_interfaces_ = [IID_IConnectableServer] +
win32com.server.connect.ConnectableServer._com_interfaces_
# The single public method that the client can call on us
# (ie, as a normal COM server, this exposes just this single
method).
def DoIt(self,arg):
# Simply broadcast a notification.
print "I am being called"
arg = arg + "_suffix"
self._BroadcastNotify(self.NotifyDoneIt, (arg,))
def NotifyDoneIt(self, interface, arg):
interface.Invoke(1000, 0, pythoncom.DISPATCH_METHOD, 1,
arg)
if __name__=='__main__':
import win32com.server.register
win32com.server.register.UseCommandLine(MyConnectableServer)
---- MyEventServer.idl ----
///////////////////////////////////////////////////////////////////
// This file (MyEventServer.idl) was written to match up with the
// implied definition in server.py
//
// To produce a type library (.tlb) just run 'midl' on this file.
//
import "oaidl.idl";
import "ocidl.idl";
// Interface IConnectableServer:
[
object,
uuid(F51A6858-F43E-4CF9-B603-6D15D3E8DB71),
dual,
helpstring("IConnectableServer Interface"),
pointer_default(unique)
]
interface IConnectableServer : IDispatch
{
[id(1000), helpstring("method DoIt")] HRESULT DoIt([in] BSTR arg);
};
///////////////////////////////////////////////
// Type Library:
[
// Every class of the form "CFoo" must contain the class attribute
// _typelib_guid_ = "{3593F5DE-2F61-43E9-8788-68D2D4C943D8}"
uuid(3593F5DE-2F61-43E9-8788-68D2D4C943D8), // top level _reg_clsid_
version(0.1),
helpstring("server 0.1 Type Library")
]
library MyEventServerLib
{
importlib("stdole32.tlb");
importlib("stdole2.tlb");
// callback (event handler) OnDoneIt
[
uuid(FCA56F6D-2291-4A32-9BDE-D577D24616F1),
helpstring("_IConnectDemoEvents Interface")
]
interface _IConnectDemoEvents : IUnknown
{
[id(1000), helpstring("method OnDoneIt")] HRESULT OnDoneIt(BSTR
Result);
}
// Class MyConnectableServer:
[
// The Python class MyConnectableServer must contain this class
attribute:
uuid(FA5F6400-DD37-4E1D-9E2C-9BEC56C4F2AE), // _reg_clsid_
helpstring("server MyConnectableServer Class")
]
coclass MyConnectableServer // _reg_progid_
{
[default] interface IConnectableServer;
[default, source] interface _IConnectDemoEvents;
};
};
_______________________________________________
Python-win32 mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-win32