Python extension module initialization - multiple files

Having created the C library, which consists of many source and header files, now I need to wrap it with a Python layer so that I can "import" it.

I have implemented a static method that should be called from Python, and I need to specify which methods the module should provide for the interpreter.

However, the documentation seems to deal with a very simple case of having one source file when it comes to determining what can be called, since the only non-static method should be init, which registers the methods.

As far as I can tell, it is not possible to call methods in other source files if they are declared static in C (please correct me if I'm wrong there), so only one C file is possible per python module, since you are allowed only one non-static method in all of this.

Is this really so? Should you structure your code poorly / not at all if you want to access it with Python?

EDIT:

So, the way I worked in the end was to use Cython . Not only did it take about an hour to rewrite the c / python interface (which previously took about a day due to all the rules of link counting, etc.), but it also handles all the build problems for you and has clear documentation describing which ones methods will be available from python.

In particular, in the chapters of the documentation that I used, there were assembly instructions on how to invoke C libraries , the basics of the language, and how to make throw types, especially pointers .

For those who want to wrap existing complex structured C code (i.e. something more than one file) as a python library, I can highly recommend Cython.

+4
source share
3 answers

In fact, the requirement for the module initialization function is not the only non-statistical symbol in the module. This is a more efficient practice that prevents contamination of the flat C namespace for run-time characters. Another common approach for this is to place a library-specific prefix for all exported characters. You can do this, although a static approach is generally considered cleaner and more reliable.

+3
source

Use the header file to make your external functions available to the compiler. This is not a Python issue, it is a common language in C.

my_prototypes.h

// declare the prototype. everybody who includes `my_prototypes.h` now knows that it exists. PyObject *func_from_other_module(PyObject *self, PyObject *args); 

anotherunit.c

  PyObject *func_from_other_module(PyObject *self, PyObject *args) { // actual implementation } 

mainunit.c

  #include "my_prototypes.h" static PyMethodDef SpamMethods[] = { {"func_from_other_module", func_from_other_module, METH_VARARGS, "Blabla"}, ... {NULL, NULL, 0, NULL} /* Sentinel */ } 

And you are right, if the static function is declared, it can be used only from the file in which it is contained. You don’t need it - just leave static (in principle, t even need a heading: placing function declarations at the top of mainunit.c also works).

+2
source

So, the way I got this work in the end was to use Cython . Not only did it take about an hour to rewrite the c / python interface (which previously took about a day due to all the rules of link counting, etc.), but it also handles all the build problems for you and has clear documentation describing which ones methods will be available from python.

In particular, in the chapters of the documentation that I used, there were assembly instructions on how to invoke C libraries , the basics of the language, and how to make throw types, especially pointers .

For those who want to wrap existing complex structured C code (i.e. something more than one file) as a python library, I can highly recommend Cython.

0
source

Source: https://habr.com/ru/post/1339874/


All Articles