Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I reference #defines in a C file from python?

I have a C file that has a bunch of #defines for bits that I'd like to reference from python. There's enough of them that I'd rather not copy them into my python code, instead is there an accepted method to reference them directly from python?

Note: I know I can just open the header file and parse it, that would be simple, but if there's a more pythonic way, I'd like to use it.

Edit:

These are very simple #defines that define the meanings of bits in a mask, for example:

#define FOO_A 0x3
#define FOO_B 0x5
like image 710
mfisch Avatar asked Aug 27 '12 18:08

mfisch


2 Answers

You might have some luck with the h2py.py script found in the Tools/scripts directory of the Python source tarball. While it can't handle complex preprocessor macros, it might be sufficient for your needs.

Here is a description of the functionality from the top of the script:

Read #define's and translate to Python code. Handle #include statements. Handle #define macros with one argument. Anything that isn't recognized or doesn't translate into valid Python is ignored.

Without filename arguments, acts as a filter. If one or more filenames are given, output is written to corresponding filenames in the local directory, translated to all uppercase, with the extension replaced by ".py".

By passing one or more options of the form "-i regular_expression" you can specify additional strings to be ignored. This is useful e.g. to ignore casts to u_long: simply specify "-i '(u_long)'".

like image 55
James Henstridge Avatar answered Oct 23 '22 19:10

James Henstridge


Running under the assumption that the C .h file contains only #defines (and therefore has nothing external to link against), then the following would work with swig 2.0 (http://www.swig.org/) and python 2.7 (tested). Suppose the file containing just defines is named just_defines.h as above:

#define FOO_A 0x3
#define FOO_B 0x5

Then:

swig -python -module just just_defines.h ## generates just_defines.py and just_defines_wrap.c
gcc -c -fpic just_defines_wrap.c -I/usr/include/python2.7 -I. ## creates just_defines_wrap.o
gcc -shared just_defines_wrap.o -o _just.so ## create _just.so, goes with just_defines.py

Usage:

$ python 
Python 2.7.3 (default, Aug  1 2012, 05:16:07) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import just
>>> dir(just)
['FOO_A', 'FOO_B', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '_just', '_newclass', '_object', '_swig_getattr', '_swig_property', '_swig_repr', '_swig_setattr', '_swig_setattr_nondynamic']
>>> just.FOO_A
3
>>> just.FOO_B
5
>>> 

If the .h file also contains entry points, then you need to link against some library (or more) to resolve those entry points. That makes the solution a little more complicated since you may have to hunt down the correct libs. But for a "just defines case" you don't have to worry about this.

like image 24
mcarifio Avatar answered Oct 23 '22 19:10

mcarifio