python, ctypes, and debugging symbols.

there is a python module called ctypes. This module lets you make calls to various functions inside a dynamically linked library without having to explicitly write wrapper code for it.  But you must specify the complete type of the function you're calling before you call it, so that the ctypes library knows arguments to push onto the stack and what order etc.

This always seemed to be a silly restriction, in an strong, but dynamically typed language such as python having to forward declare things seems to defeat the entire purpose.  And besides, when you compile something, you can compile it with full debugging symbols, which has the full type information about everything in your program anyway.

So, you could write a program to parse the debugging symbols out of an .so, and generate a python module with all the various type definitions and functions exported from the library, and you could do all of this on the fly.

And thus, I wrote it.

foo.c

struct function2_return_t {
        int a;
        int b;
};

struct function2_return_t function2(int a)
{
        struct function2_return_t ret;
        ret.a=a;
        ret.b=a+1;

return ret;
}

And the example usage:

>>> import ct
>>> ct.load("foo.so")
>>> import foo
>>> ret=foo.function2(1)
>>> print ret
<ct.function2_return_t object at 0x2aefd8f12650>
>>> print ret.a
1
>>> print ret.b
2

It's all still very prototypeish, it doesn't deal with pointers or strings yet. As you can see it deals with structs (as if they were classes), and could fairly easily deal with arrays and pointers to structs (although once you get into pointers, you get into "who owns this memory", perhaps requiring a .free() method on classes).  Strings should also be fairly straight forward if you can figure out who actually owns the memory (should it be freed?).

At the moment I run and parse the output of readelf to get the debugging information, and I don't properly hook the "import" mechanism to make it all completely transparent, but as a prototype I thought it was pretty cool. 

Comments are closed.