Import constants from .h file into python

前端 未结 4 993
青春惊慌失措
青春惊慌失措 2021-02-07 09:56

I\'ve been looking for a simple answer to this question, but it seems that I can\'t find one. I would prefer to stay away from any external libraries that aren\'t already includ

4条回答
  •  梦谈多话
    2021-02-07 10:36

    In general, defining variables in C header file is poor style. The header file should only declare objects, leaving their definition for the appropriate ".c" source code file.

    One thing you may want to do is to declare the library-global constants like extern const whatever_type_t foo; and define (or "implement") them (i.e. assigning values to them) somewhere in your C code (make sure you do this only once).

    Anyway, let's ignore how you do it. Just suppose you've already defined the constants and made their symbols visible in your shared object file "libfoo.so". Let us suppose you want to access the symbol pi, defined as extern const double pi = 3.1415926; in libfoo, from your Python code.

    Now you typically load your object file in Python using ctypes like this:

    >>> import ctypes
    >>> libfoo = ctypes.CDLL("path/to/libfoo.so")
    

    But then you'll see ctypes thinks libfoo.pi is a function, not a symbol for constant data!

    >>> libfoo.pi
    <_FuncPtr object at 0x1c9c6d0>
    

    To access its value, you have to do something rather awkward -- casting what ctypes thinks is a function back to a number.

    >>> pi = ctypes.cast(foo.pi, ctypes.POINTER(ctypes.c_double))
    >>> pi.contents.value
    3.1415926
    

    In C jargon, this vaguely corresponds to the following thing happening: You have a const double pi, but someone forces you to use it only via a function pointer:

    typedef int (*view_anything_as_a_function_t)(void);
    view_anyting_as_a_function_t pi_view = π
    

    What do you do with the pointer pi_view in order to use the value of pi? You cast it back as a const double * and dereference it: *(const double *)(pi_view).

    So this is all very awkward. Maybe I'm missing something but this I believe is by design of the ctypes module -- it's there chiefly for making foreign function calls, not for accessing "foreign" data. And exporting pure data symbol in a loadable library is arguably rare.

    And this will not work if the constants are only C macro definitions. There's in general no way you can access macro-defined data externally. They're macro-expanded at compile time, leaving no visible symbol in the generated library file, unless you also export their macro values in your C code.

提交回复
热议问题