ctypes: How to call unexported functions in a dll

Thomas Heller theller at python.net
Tue Jan 5 16:02:59 CET 2010


Am 05.01.2010 12:19, schrieb Coert Klaver (DT):
> Hi,
> 
> I am using ctypes in python 3 on a WXP machine
> 
> Loading a dll and using its exported functions works fine.
> 
> Now I want to use a function in the dll that is not exported.
> 
> In C this can be done by just casting the address in the dll of that
> function to an apropriate function pointer and call it (you need to be
> sure about the address). Can a similar thing be done directly with
> ctypes?
> 
> A work around I see is writing in wrapper dll in c that loads the main
> dll, exports a function that calls the unexported function in the main
> dll, but I don't find that an elegant solution.

No need for a workaround.

One solution is to first create a prototype for the function by calling WINFUNCTYPE
or CFUNCTYPE, depending on the calling convention: stdcall or cdecl, then call the
prototype with the address of the dll function which will return a Python callable.
Demonstrated by the following script using GetProcAddress to get the address of
the GetModuleHandleA win32 api function:

>>> from ctypes import *
>>> dll = windll.kernel32
>>> addr = dll.GetProcAddress(dll._handle, "GetModuleHandleA")
>>> print hex(addr)
0x7c80b741
>>> proto = WINFUNCTYPE(c_int, c_char_p)
>>> func = proto(addr)
>>> func
<WinFunctionType object at 0x00AD4D50>
>>> func(None)
486539264
>>> hex(func(None))
'0x1d000000'
>>> hex(func("python24.dll"))
'0x1e000000'
>>> hex(func("python.exe"))
'0x1d000000'
>>>

Thomas



More information about the Python-list mailing list