Edward Sr schrieb am 10.04.22 um 19:09:
> I know that there's already a similar thread here
> my desired solution is different, more strict.
Thanks for searching, and for providing the reference.
> I have a C code, and I'm wrapping some internal functions using Cython.
> Now since they are internal functions, I MUST work with static libraries
> instead of shared (Linux environment).
> In the internal C code, there's a global (extern) static variable, that is
> modified and accessed from multiple different C files.
That's unfortunate but not so uncommon. You are right that this means you
have to make sure the library is only there once. Or, that at least those
parts of the library that depend on that global variable are only used from
one library instance.
> My problem is that, since Cython libraries are shared, the value of this
> variable differs depending on which Cython module I'm using... which
> affects the result of the functions I'm wrapping.
> I don't access the get/set of this variable or the variable itself directly
> from the Cython code.
> Assuming that I can't change the C code (at least not refactoring, like
> moving functions from place to place or changing the variable to not be
> global...), how can I resolve this issue via Cython?!!
> I also don't want to put all modules into one file, because the project is
> not small at all, and has multiple hierarchies.
What I would try is to have one low-level Cython extension module that
wraps the C library with a C interface (of cdef functions and maybe some
basic extension types), exposed in the corresponding lowlevelmodule.pxd
file (with the same name as the module). Then, other modules no longer need
to link against the library but can cimport the low-level extension module
and call into the C library through that. Internally, this cimport
mechanism uses CPython's PyCapsule mechanism for exposing C-APIs from
You can still mix this approach with other statically linked extension
modules, as long as those do not need to share state with the low-level
wrapper module (which owns the state of the global variable). I'm actually
doing that in lxml's etree and objectify modules (rather by accident),
which both link against libxml2, but all configurable functionality resides
in lxml.etree – objectify only uses library functions that operate
independently. So, this can work, and allows for trading a somewhat larger
package size (more copies of the library) for speed (direct library calls,
e.g. for short-running functions).
> I will write a song in binary for whoever helps me solve this!! :D
Let's hear more from that. :)