Re: [ctypes-users] Pointers to int or Char*
Brought to you by:
theller
From: Thomas H. <th...@py...> - 2003-04-14 15:17:16
|
"Mark McMahon" <mar...@eu...> writes: > Hi Tomas, > > It didn't work ;( > (python 2.2, CVS ctypes from a couple of days ago) Mark, thanks for the report. The code I posted was buggy, but it was somewhat funny to track down. For now, here is code that works, both for ANSI and UNICODE. The problem was that c_char_p.from_address(...) was not correct, because it expects an address where a 'pointer to a string' is stored, but it receives the address where the first character is stored ;-(. The deeper problem was (is?) that an access violation in the callback function (my_enum_proc) is catched by the win32 structured exception handling handler for the EnumResourceTypesA() call, but without releasing Python's global interpreter lock again, so the code keeps waiting for the gil, until you interrupt it with CTRL-Break. > I also was wondering if there was any easy way to pass python objects to > functions (for example the 3rd parameter to EnumResourceTypes), I did > use the method that you outlined in the thread "Converting instances to > address and back". But that seems like hackery, and I am wondering if > there is an easier way. I think the 3rd parameter in the win32 enum... functions is for languages less powerful than python - those which don't have bound methods. In Python, I would use a bound method as the my_enum_proc, which will then automatically receive the 'self' parameter, and you use the instance variables. Thomas #-------------------------------------- from ctypes import * import ctypes # for _LoadLibrary import os import os.path class RES_A(Union): _fields_ = [("int", c_int), ("str", c_char_p)] def _get_value(self): if self.int & 0xFFFF0000: return self.str return self.int value = property(_get_value) class RES_W(RES_A): _fields_ = [("int", c_int), ("str", c_wchar_p)] def my_enum_proc(hModule, lpszType, lParam): print repr(lpszType.value) return 1 EnumResTypeProcW = WINFUNCTYPE(c_int, c_int, RES_W, c_int) EnumResTypeProcA = WINFUNCTYPE(c_int, c_int, RES_A, c_int) lib = ctypes._LoadLibrary(os.path.join(r"c:\windows\\system32", r"shell32.dll")) print "-"*15, "UNICODE", "-"*15 windll.kernel32.EnumResourceTypesW(lib, EnumResTypeProcW(my_enum_proc), 0) print "-"*15, "ANSI", "-"*15 windll.kernel32.EnumResourceTypesA(lib, EnumResTypeProcA(my_enum_proc), 0) #---------------------------------------- On my system, this code prints: --------------- UNICODE --------------- u'AVI' u'REGINST' u'TYPELIB' u'UIFILE' 1 2 3 4 5 6 9 12 14 16 23 24 --------------- ANSI --------------- 'AVI' 'REGINST' 'TYPELIB' 'UIFILE' 1 2 3 4 5 6 9 12 14 16 23 24 |