Re: [ctypes-users] Win32 access violation in cdll call to _xpcom. cif->abi is FFI_SYSV?
Brought to you by:
theller
From: Brad C. <bk...@mu...> - 2004-08-28 01:06:01
|
I am tracking this down using the VC debugger (on Win2k) with 0.9.1 and I note two odd things. First, I'm calling into pyxpcom.pyd. It exports a function declared like this in pyXPCOM.h: inline PYXPCOM_EXPORT PRBool IIDFromPyObject(PyObject *ob, nsIID *pRet) { return Py_nsIID::IIDFromPyObject(ob, pRet); } My python script looks like this: xpcom_dll = CDLL('_xpcom.pyd') IIDFromPyObject = xpcom_dll.IIDFromPyObject IIDFromPyObject.argtypes = [PyObject, c_void_p] IIDFromPyObject.restype = int # convert mozilla type to an iid browser_IID = "@mozilla.org/embedding/browser/nsWebBrowser;1" # get pointer to it IID_Type = c_char * 128 IID = IID_Type() raw_input("enter for crash") res = IIDFromPyObject(browser_IID, byref(IID)) I've traced this throgh CFuncPtr_Call, into _CallProc I note in _call_function_pointer: flags & FUNCFLAG_PYTHONAPI == 0 Somehow I need to set this flag from Python so that the GIL is not released. How do I do that? And then, in ffi_call cif->abi == FFI_SYSV Shouldn't cif->abi be FFI_STDCALL ? And then it crashes somewhere in Python because ffi_call has gone somewhere it shouldn't. I must have missed something obvious in the docs. should xpcom_dll = CDLL('_xpcom.pyd') be xpcom_dll = WINDLL('_xpcom.pyd') ah ah aha .. light bulb goes off. Ok, so I created this class: class WINPYDLL(CDLL): class _StdcallFuncPtr(_CFuncPtr): _flags_ = _FUNCFLAG_STDCALL | _FUNCFLAG_PYTHONAPI _restype_ = c_int # default, can be overridden in instances def __getattr__(self, name): if name[:2] == '__' and name[-2:] == '__': raise AttributeError, name func = self._StdcallFuncPtr(name, self) setattr(self, name, func) return func then did this: xpcom_dll = WINPYDLL('_xpcom.pyd') Now when I call res = IIDFromPyObject(browser_IID, byref(IID)) I get this: Traceback (most recent call last): File "O:\Python\mozcontrol\mozaxwindow.py", line 226, in __init__ aBrowser.get_aBrowser() File "O:\Python\mozcontrol\mozaxwindow.py", line 155, in get_aBrowser res = IIDFromPyObject(browser_IID, byref(IID)) ValueError: Procedure probably called with too many arguments (8 bytes in excess ) 8 bytes, that's two pointers worth. So, someone left them on the stack I guess. That means that it should be .. CDECL ? but won't that get me back into FFI_SYSV again? -- Brad Clements, bk...@mu... (315)268-1000 http://www.murkworks.com (315)268-9812 Fax http://www.wecanstopspam.org/ AOL-IM: BKClements |