Fatal Python error using ctypes & python exceptions

Thomas Heller theller at ctypes.org
Fri Aug 31 17:55:23 CEST 2007


mmacrobert schrieb:
> Hi Everyone,
> I've created a 'C' dll that is accessed via ctypes library containing
> a bunch of functions. I've successfully been able to use the
> functions. However, I would like to throw python exceptions from some
> of them.
> 
> I throw them using: ::PyErr_SetString(::PyExc_RuntimeError,
> theErrorString);
> 
> I crash the console when this function is invoked in the 'C' domain. I
> get an error stating:
> 
> Fatal Python error: PyThreadState_Get: no current thread
> 
> when the calling code in python is:
> 
> try:
>     cdll.MyDll.ThrowingFunction()
> except:
>     print "An error has occurred"
> 
> The dll is just a plain win32 'C' dll, built with an MS compiler. How
> do I throw python exceptions correctly? Is there some kind of "init"
> function that needs to be called?

For libraries loaded with cdll.MyDll or CDLL("MyDll") ctypes releases
the GIL before calling the function, and reacquires the GIL afterwards.

This has the consequence that you cannot use any Python api functions
inside the dll functions (because there is no ThreadState, just like
the error message says).

If you want to throw Python exceptions in the dlls functions, or use
other Python apis, you must use the 'Python calling convention'.
For this calling convention the GIL is NOT released and reacquired,
but after the function call returns PyErr_Occurred() is called and an
exception raised in the calling code - exactly what you want.

The 'Python calling convention' is used when you load the library
with pydll.MyDll or PyDLL("MyDll").

Additional remark:  You can have functions with different calling
conventions in the same dll, just load it with different library loaders
and you're fine.

Thomas




More information about the Python-list mailing list