Sometimes, a dll not only exports functions, it also exports
variables. An example in the Python library itself is the
Py_OptimizeFlag, an integer set to 0, 1, or 2, depending on the
-O or -OO flag given on startup.
ctypes can access values like this with the in_dll class
methods of the type. pythonapi ìs a predefined symbol giving
access to the Python C api:
>>> opt_flag = c_int.in_dll(pythonapi, "Py_OptimizeFlag") >>> print opt_flag c_long(0) >>>
If the interpreter would have been started with -O, the sample
would have printed
c_long(2) if -OO would have
An extended example which also demonstrates the use of pointers
PyImport_FrozenModules pointer exported by Python.
Quoting the Python docs: This pointer is initialized to point to an array of ``struct _frozen`` records, terminated by one whose members are all NULL or zero. When a frozen module is imported, it is searched in this table. Third-party code could play tricks with this to provide a dynamically created collection of frozen modules.
So manipulating this pointer could even prove useful. To restrict the
example size, we show only how this table can be read with
>>> from ctypes import * >>> >>> class struct_frozen(Structure): ... _fields_ = [("name", c_char_p), ... ("code", POINTER(c_ubyte)), ... ("size", c_int)] ... >>>
We have defined the
struct _frozen data type, so we can get the
pointer to the table:
>>> FrozenTable = POINTER(struct_frozen) >>> table = FrozenTable.in_dll(pythonapi, "PyImport_FrozenModules") >>>
table is a
pointer to the array of
records, we can iterate over it, but we just have to make sure that
our loop terminates, because pointers have no size. Sooner or later it
would probably crash with an access violation or whatever, so it's
better to break out of the loop when we hit the NULL entry:
>>> for item in table: ... print item.name, item.size ... if item.name is None: ... break ... __hello__ 104 __phello__ -104 __phello__.spam 104 None 0 >>>
The fact that standard Python has a frozen module and a frozen package
(indicated by the negative size member) is not wellknown, it is only
used for testing. Try it out with
import __hello__ for example.
See About this document... for information on suggesting changes.