From: Thomas H. <th...@ct...> - 2008-07-30 19:48:37
|
MR Michael Robellard (5314) schrieb: > Hello, > > I am trying to implement the IURLSearchHook2 interface in comtypes and I > am running into some issues. > > which generate the following in the comtypes.gen .py files: > class IURLSearchHook2(IURLSearchHook): > _case_insensitive_ = True > _iid_ = GUID('{5EE44DA4-6D32-46E3-86BC-07540DEDD0E0}') > _idlflags_ = [] > IURLSearchHook2._methods_ = [ > COMMETHOD([], HRESULT, 'TranslateWithSearchContext', > ( ['in', 'out'], WSTRING, 'lpwszSearchURL' ), > ( ['in'], c_ulong, 'cchBufferSize' ), > ( ['in'], POINTER(ISearchContext), 'pSearchContext' )), > ] > I can get the data into the method and print it out fine. > The problem is when I try and return a string out. It just plain hangs. > If anyone has any thoughts. Is this even possible? > I have tried both the "high level" and "low level" approach as discussed > in Thomas' recent post Mike, here are my thoughts on your problem. The high level comtypes method implementation can only work for automation-compatible argument types, and WSTRING is not one of those. WSTRING is defined as c_wchar_p in the generated file. c_wchar_p is interpreted as a zero-terminated wide character string, but what COM really passes is a buffer with space for 'cchBufferSize' wide characters. Which contains a zero-terminated string that you are supposed to change. comtypes assumes c_wchar_p as 'const' strings which you cannot/should not change. I think you should change the 'TranslateWithSearchContext' method definition to something like this: > IURLSearchHook2._methods_ = [ > COMMETHOD([], HRESULT, 'TranslateWithSearchContext', > ( ['in', 'out'], POINTER(c_wchar), 'lpwszSearchURL' ), > ( ['in'], c_ulong, 'cchBufferSize' ), > ( ['in'], POINTER(ISearchContext), 'pSearchContext' )), > ] and write the (low-level) implementation like so: def TranslateWithSearchContext(self, this, lpwszSearchURL, cchBufferSize, pSearchContext): # lpwszSearchURL is a POINTER(c_wchar) instance. rawdata = lpwszSearchURL[:cchBufferSize] # rawdata is now a unicode string of length cchBufferSize, filled with NUL characters # at the end. The [in] unicode string can probably be get by this: url = rawdata.split('\0')[0] # Maybe ctypes.wstring_at(lpwszSearchURL) would also work. # The [out] string must be written into the lpwszSearchURL buffer, maybe this works: lpwszSearchURL[:cchBufferSize] = '\0' * cchBufferSize # clear it urlout = "http://web.somewhere.whatdoIknow" lpwszSearchURL[:len(urlout)] = urlout return S_OK Thomas |