CInvoke
Description
CInvoke is a way to call your C functions from Python. It is
similar to ctypes
in concept, but implemented very differently.
The package features:
-
cinvoke: The Python/C pipe-based bridge.
-
DataTypes: Some very generic code I would like to see built
into Python. Until then, I use it from here. I narrowed it
down to the minimal subset used by CInvoke, for distribution
purposes.
-
DataTypes.CDataTypes: A powerful replacement for the built-in
struct module. A generic c-type library that is used with
CInvoke.
-
OSUtils.Executables: A library to parse executables. Currently
it is a very limited implementation that uses "readelf" to
parse only ELF formats. In the future, real DWARF parsing and
hopefully COFF parsing will be implemented.
CInvoke
-
Uses a socket/pipe to control the C side, allowing it
to control multiple processes.
-
Cannot cause segmentation faults in the hosting Python
interpreter process. At worst, the controlled process dies,
and the pipe to it is closed.
-
Can control processes on remote computers.
-
Can be used side-by-side a mainloop of an existing C program.
-
Allows testing C programs in a more "realistic" environment,
without the Python interpreter around it (This is relevant if
your program installs signal handlers, manages its memory
space, etc).
-
Allows nesting request handling loops inside stubbed
(replaced) functions. This allows for very powerful error
injection, controlling the execution of these replaced
functions from Python. It is also useful to halt the C
process in a specific point, in which time the Python can
command other C processes.
-
Limitation: CInvoke requires building your program differently
(With symbol information and a custom main() or server call
code). Hopefully, I will find a way to use ldpreload or other
tricks in order to avoid the main() replacement, and ease
replacing of functions with stubs. In any case, compilation
with Symbols will still be required. Note that compiling with
-g and using strip is possible, in order to create both a
stripped and non-stripped version of the same executable.
-
Limitation: CInvoke currently uses readelf to extract the
symbols and debug information from the executable. This means
CInvoke is currently ELF-only. In the future, I plan to
create and use a Pythonic executable parsing library or wrap
an existing one and support many executable and debug
information formats.
DataTypes
-
Various small and useful modules, required by the above
libraries. Probably worth a look, if you are a Pythoneer.
DataTypes.CDataTypes
-
Support for all basic C types, Unions, Structs, Enums, Arrays, and Pointers.
-
Pointer dereference semantics are defined by the
user. Dereferences can be defined to access any arbitrary
address space, for example: A remote C process's address
space, a file address space, a mutable string, ...
Download
CInvoke can be downloaded here.
A simple example can be found inside the Example directory.
The current installer is very lame, and does not install the C
code anywhere, I have only had about 15 minutes to work the
setup.py and installation so far, sorry! :-) For now you can just
use "make" inside the server directory to make a linkable server,
or use "make" inside the example directory to make the example.
Bug reports
Please report bugs to
Eyal Lotem.
Note that the "assertion failed" in the end of the "test" is not a
bug, but the current way to handle errors in the server. Assertion
failures are much easier to debug than bad return codes and more
useful for unit tests, and currently this happens in EOF too. In
the future assertion failures will be an optional way to error
handle, and EOF will definitely not be an error.
Eyal Lotem
Last modified: Sat Aug 19 16:08:50 IDT 2006