embedding Python in COM server loaded with win32com

Stefan Schukat SSchukat at dspace.de
Tue Jun 6 05:11:50 EDT 2006


Hi,

when you are running in Python the PyInitialize() is not called and 
therefore you don't have a valid threadstate since the call in win32com
uses the standard idiom 

Py_BEGIN_ALLOW_THREADS()
CallComServer
Py_END_ALLOW_THREADS()


You could use PyNewInterpreter to get a valid state, but this won't work
in 
Python greater version 2.2, since with the new GILState API does not
allow more
than one interpreter per thread. You could work around the problem if
you would use 
a localserver instead of an inproc server. With that you would always
have
a clean process for your server.

	Stefan

> -----Original Message-----
> From: python-list-bounces+sschukat=dspace.de at python.org 
> [mailto:python-list-bounces+sschukat=dspace.de at python.org] On 
> Behalf Of Fozzie
> Sent: Monday, June 05, 2006 3:57 PM
> To: python-list at python.org
> Subject: embedding Python in COM server loaded with win32com
> 
> Hi,
> 
> I have a problem which is quite circular, and hopefully 
> either someone has encountered something similar or has a 
> reason why this will not work.
> 
> We have a COM library providing mathematics to various 
> systems, most functions are hard-coded but we want to embed a 
> scripting language to allow arbitrary functions to be used in 
> the numeric engines within the library, and am using Python for this.
> 
> This seems to work fine called from standalone apps, and from 
> VB, however, Python scripts, which access the scripts via 
> win32com.client fail in the embedding code in C++ whenever I 
> attempt to call PyImport_AddModule.
> 
> As a concrete example, consider the following minimal 
> interface, (created using an ATL project in VC7),  which has 
> a single property, the user supplied script, and a single 
> function 'findRoot', which in this case is nothing more than 
> an indicator that the embedding worked,
> 
> -------------------------------------------------------------
> STDMETHODIMP CMinEmbed::get_script(BSTR* pVal) {
> 	USES_CONVERSION;
> 	*pVal = SysAllocString(A2OLE(__script.c_str()));
> 	return S_OK;
> }
> STDMETHODIMP CMinEmbed::put_script(BSTR newVal) {
> 	USES_CONVERSION;
> 	__script = std::string( OLE2A( newVal));
> 	return S_OK;
> }
> STDMETHODIMP CMinEmbed::findRoot(DOUBLE* root) {
> 	std::string progress;
> 	PyObject * main, * globals, * res, * func;
> 
> 	try {
> 
> 		progress = "calling PyInitialize";
> 		if(!Py_IsInitialized()) Py_Initialize();
> 
> 		progress = "get __main__ module";
> 		main = PyImport_AddModule("__main__");
> 
> 		progress = "get __main__module dictionary";
> 		globals = PyModule_GetDict(main);
> 
> 		progress = "Run the script.";
> 		res = PyRun_String(__script.c_str(), 
> Py_file_input, globals, globals);
> 
> 		progress = "Get the function from main dictionary.";
> 		func = PyDict_GetItemString(globals, "func");
> 
> 		progress = "test function, and return indicator";
> 		if(NULL != func && PyCallable_Check(func)) {
> 			*root = 1.0;
> 		} else {
> 			*root = -1.0;
> 		}
> 
> 		progress = "clean up";
> 		Py_XDECREF(res);
> 		Py_Finalize();
> 		return S_OK;
> 
> 	} catch(...) {
> 		// SetFailString just sets the 
> ISupportErrorInfo interface
> 		SetFailString(IID_IMinEmbed, progress.c_str());
> 		return E_FAIL;
> 	}
> }
> -------------------------------------------------------------
> 
> 
> When I build my server with the above method and run it at 
> the Python interpretor I get,
> 
> >>> from win32com.client import Dispatch s = 
> >>> Dispatch('minServer.MinEmbed') s.script = 'def func(x) : 
> return x*x'
> >>> s.findRoot()
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
>   File "<COMObject minServer.MinEmbed>", line 2, in findRoot
>   File 
> "i:\1111\Python24\lib\site-packages\win32com\client\dynamic.py",
> line 251, in _ApplyTypes_
>     result = self._oleobj_.InvokeTypes(*(dispid, LCID, 
> wFlags, retType,
> argTypes) + args)
> pywintypes.com_error: (-2147352567, 'Exception occurred.', 
> (0, None, 'Failure to get main module', None, 0, -2147467259), None)
> 
> However, works fine from VB and standalone apps.
> 
> Is this approach even doable? 
> 
> 
> Thanks in advance 
> 
> 
> Dave Foster
> 
> --
> http://mail.python.org/mailman/listinfo/python-list
> 



More information about the Python-list mailing list