cdef to support #define and #include

Issue #5 wontfix
ישראל פרוכטר
created an issue

I would be very helpful if we could do thinks like that: {{{


ffi.cdef(""" #include <WinDef.h> #define in #define in_out #define out #define WINAPI stdcall """


and all the definitions from WinDef should be included in the lib after the ffi.verify call

Comments (7)

  1. Armin Rigo
    • changed status to open

    There are two ways to solve this: we can add some complicated rules for #defines and #includes in cdef() --- which we may need to have at some point anyway --- or we might just add what you typed as special cases on Windows. This would be done simply by removing "in" and friends in the same way as we remove comments, and adding support for the types declared in WinDef.h.

  2. Sarvi Shanmugham

    A suggestion on what would be usefull when considering this implementation

    1. The option to ignore all #includes except a select list of them. It was explained to me earlier on this list why automatically including all #includes recursively would be a bad idea. Made sense to me. So the option to automatically includes only specific include files provided as an option to cdef or established with ffi through a separate api would be usefull. These headers will be automatically expanded, the rest will ignored.

    2. process and honour #ifdef style macros

    3. translate all simple #define operations that can be translated to "..." be done automatically and the rest of the more complex #defines that cannot be processed properly by cdef be ignored instead of erroring out.

  3. Dan Miller

    A workaround for this in the meanwhile would be to expose pycparser's ability to run code through the preprocessor first. These would be the arguments use_cpp and cpp_args in pycparser's parse_file function.

  4. Armin Rigo

    Unlikely to ever do this in CFFI. Preprocessing the cdef is likely to raise more questions than it solves, like what should we do with all function declarations that come with some unrelated #include or how to handle all these Linux-only GCC extensions used in the headers. On the other hand, Sarvi's solution of selectively ignoring parts of the cdef following some complex rules is best implemented outside cffi, by preprocessing what you pass to cdef() yourself following the rules that make sense for your project.

  5. Dan Miller

    I'm going to throw this out there as a potential long-term fix, though it would be a major architectural change: Migrate the AST parsing from pycparser to libclang.

    I've done this with most of my own code and found libclang to be much more robust. It handles the all the preprocessing and saves a lot more metadata about the AST, such as filename, etc.. The Python bindings are easy to work with.

    I could understand there being philosophical objections to this, since it's not a pure Python solution. Any thoughts?

  6. ישראל פרוכטר reporter

    I would argure that without it it would be very hard to use cffi for any big enough apis, I can understand why preprossing is hard. Some type of preprossing is needed if you want to keep you .h files DRY and avoid repeating same defines in each place you're going to use it in cffi.

    I'm not familiar with clang, but surly even a hack to use the complied itself to do the preprocessing step might be useful.

  7. Log in to comment