@@ -3814,13 +3814,118 @@ Other conversions
3814
3814
in the *vals* array. The sequence can be smaller then *maxvals* as
3815
3815
the number of converted objects is returned.
3816
3816
3817
+ .. _including-the-c-api:
3817
3818
3818
- Miscellaneous
3819
- -------------
3819
+ Including and importing the C API
3820
+ ---------------------------------
3820
3821
3822
+ To use the NumPy C-API you typically need to include the
3823
+ ``numpy/ndarrayobject.h`` header and ``numpy/ufuncobject.h`` for some ufunc
3824
+ related functionality (``arrayobject.h `` is an alias for ``ndarrayobject.h ``).
3821
3825
3822
- Importing the API
3823
- ~~~~~~~~~~~~~~~~~
3826
+ These two headers export most relevant functionality. In general any project
3827
+ which uses the NumPy API must import NumPy using one of the functions
3828
+ ``PyArray_ImportNumPyAPI()`` or ``import_array()``.
3829
+ In some places, functionality which requires ``import_array()`` is not
3830
+ needed, because you only need type definitions. In this case, it is
3831
+ sufficient to include ``numpy/ndarratypes.h``.
3832
+
3833
+ For the typical Python project, multiple C or C++ files will be compiled into
3834
+ a single shared object (the Python C-module) and ``PyArray_ImportNumPyAPI()``
3835
+ should be called inside it's module initialization.
3836
+
3837
+ When you have a single C-file, this will consist of::
3838
+
3839
+ .. code-block:: c
3840
+
3841
+ #include " numpy/ndarrayobject.h"
3842
+
3843
+ PyMODINIT_FUNC PyInit_my_module(void)
3844
+ {
3845
+ if (PyArray_ImportNumPyAPI () < 0) {
3846
+ return NULL;
3847
+ }
3848
+ /* Other initialization code. */
3849
+ }
3850
+
3851
+ However, most projects will have additional C files which are all
3852
+ linked together into a single Python module.
3853
+ In this case, the helper C files typically do not have a canonical place
3854
+ where ``PyArray_ImportNumPyAPI `` should be called (although it is OK and
3855
+ fast to call it often).
3856
+
3857
+ To solve this, NumPy provides the following pattern that the the main
3858
+ file is modified to define ``PY_ARRAY_UNIQUE_SYMBOL `` before the include:
3859
+
3860
+ .. code-block :: c
3861
+ /* Main module file */
3862
+ #define PY_ARRAY_UNIQUE_SYMBOL MyModule
3863
+ #include "numpy/ndarrayobject.h"
3864
+
3865
+ PyMODINIT_FUNC PyInit_my_module(void)
3866
+ {
3867
+ if (PyArray_ImportNumPyAPI() < 0) {
3868
+ return NULL;
3869
+ }
3870
+ /* Other initialization code. */
3871
+ }
3872
+
3873
+ while the other files use:
3874
+
3875
+ .. code-block :: C
3876
+
3877
+ /* Second file without any import */
3878
+ #define NO_IMPORT_ARRAY
3879
+ #define PY_ARRAY_UNIQUE_SYMBOL MyModule
3880
+ #include "numpy/ndarrayobject.h"
3881
+
3882
+ You can of course add the defines to a local header used throughout.
3883
+ You just have to make sure that the main file does _not_ define
3884
+ ``NO_IMPORT_ARRAY ``.
3885
+
3886
+ For ``numpy/ufuncobject.h `` the same logic applies, but the unique symbol
3887
+ mechanism is ``#define PY_UFUNC_UNIQUE_SYMBOL `` (both can match).
3888
+
3889
+ Additionally, you will probably wish to add a
3890
+ ``#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION ``
3891
+ to avoid warnings about possible use of old API.
3892
+
3893
+ .. note ::
3894
+ If you are experiencing access violations make sure that the NumPy API
3895
+ was properly imported and the symbol ``PyArray_API `` is not ``NULL ``.
3896
+ When in a debugger, this symbols actual name will be
3897
+ ``PY_ARRAY_UNIQUE_SYMBOL``+``PyArray_API ``, so for example
3898
+ ``MyModulePyArray_API `` in the above.
3899
+ (E.g . even a ``printf("%p\n", PyArray_API); `` just before the crash.)
3900
+
3901
+
3902
+ Mechanism details and dynamic linking
3903
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3904
+
3905
+ The main part of the mechanism is that without NumPy needs to define
3906
+ a ``void **PyArray_API `` table for you to look up all functions.
3907
+ Depending on your macro setup, this takes different routes depending on
3908
+ whether :c:macro: `NO_IMPORT_ARRAY ` and :c:macro: `PY_ARRAY_UNIQUE_SYMBOL `
3909
+ are defined:
3910
+
3911
+ * If neither is defined, the C-API is declared to
3912
+ ``static void **PyArray_API ``, so it is only visible within the
3913
+ compilation unit/file using ``#includes numpy/arrayobject.h ``.
3914
+ * If only ``PY_ARRAY_UNIQUE_SYMBOL `` is defined (it could be empty) then
3915
+ the it is declared to a non-static ``void ** `` allowing it to be used
3916
+ by other files which are linked.
3917
+ * If ``NO_IMPORT_ARRAY `` is defined, the table is declared as
3918
+ ``extern void ** ``, meaning that it must be linked to a file which does not
3919
+ use ``NO_IMPORT_ARRAY`.
3920
+
3921
+ The ``PY_ARRAY_UNIQUE_SYMBOL `` mechanism additionally mangles the names to
3922
+ avoid conflicts.
3923
+
3924
+
3925
+ .. versionchanged ::
3926
+ NumPy 2.0 exports the headers to avoid sharing the table outside of a
3927
+ single shared object/dll (this was always the case on Windows).
3928
+ Please see :c:macro: `NPY_API_SYMBOL_ATTRIBUTE ` for details.
3824
3929
3825
3930
In order to make use of the C-API from another extension module, the
3826
3931
:c:func: `import_array ` function must be called. If the extension module is
@@ -3844,61 +3949,45 @@ the C-API is needed then some additional steps must be taken.
3844
3949
module that will make use of the C-API. It imports the module
3845
3950
where the function-pointer table is stored and points the correct
3846
3951
variable to it.
3952
+ This macro includes a ``return NULL;`` on error, so that
3953
+ ``PyArray_ImportNumPyAPI() `` is preferable for custom error checking.
3954
+ You may also see use of ``_import_array() `` (a function, not
3955
+ a macro, but you may want to raise a better error if it fails) and
3956
+ the variations ``import_array1(ret) `` which customizes the return value.
3847
3957
3848
3958
.. c :macro :: PY_ARRAY_UNIQUE_SYMBOL
3849
3959
3850
- .. c:macro:: NO_IMPORT_ARRAY
3960
+ .. c :macro :: NPY_API_SYMBOL_ATTRIBUTE
3851
3961
3852
- Using these #defines you can use the C-API in multiple files for a
3853
- single extension module. In each file you must define
3854
- :c:macro: `PY_ARRAY_UNIQUE_SYMBOL ` to some name that will hold the
3855
- C-API (*e.g. * myextension_ARRAY_API). This must be done **before**
3856
- including the numpy/arrayobject.h file. In the module
3857
- initialization routine you call :c:func:`import_array`. In addition,
3858
- in the files that do not have the module initialization
3859
- sub_routine define :c:macro:`NO_IMPORT_ARRAY` prior to including
3860
- numpy/arrayobject.h.
3861
-
3862
- Suppose I have two files coolmodule.c and coolhelper.c which need
3863
- to be compiled and linked into a single extension module. Suppose
3864
- coolmodule.c contains the required initcool module initialization
3865
- function (with the import_array() function called). Then,
3866
- coolmodule.c would have at the top:
3962
+ .. versionadded :: 2.0
3867
3963
3868
- .. code-block:: c
3964
+ An additional symbol which can be used to share e.g . visibility beyond
3965
+ shared object boundaries.
3966
+ By default, NumPy adds the C visibility hidden attribute (if available):
3967
+ ``void __attribute__((visibility("hidden"))) **PyArray_API; ``.
3968
+ You can change this by defining ``NPY_API_SYMBOL_ATTRIBUTE ``, which will
3969
+ make this:
3970
+ ``void NPY_API_SYMBOL_ATTRIBUTE **PyArray_API; `` (with additional
3971
+ name mangling via the unique symbol).
3869
3972
3870
- #define PY_ARRAY_UNIQUE_SYMBOL cool_ARRAY_API
3871
- # include numpy/arrayobject.h
3973
+ Adding an empty `` #define NPY_API_SYMBOL_ATTRIBUTE `` will have the same
3974
+ behavior as NumPy 1. x .
3872
3975
3873
- On the other hand, coolhelper.c would contain at the top:
3976
+ .. note ::
3977
+ Windows never had shared visbility although you can use this macro
3978
+ to achieve it. We generally discourage sharing beyond shared boundary
3979
+ lines since importing the array API includes NumPy version checks.
3980
+
3981
+ .. c :macro :: NO_IMPORT_ARRAY
3982
+
3983
+ Defining ``NO_IMPORT_ARRAY `` before the ``ndarrayobject.h `` include
3984
+ indicates that the NumPy C API import is handled in a different file
3985
+ and the include mechanism will not be added here.
3986
+ You must have one file without ``NO_IMPORT_ARRAY `` defined.
3874
3987
3875
- .. code-block :: c
3876
3988
3877
- #define NO_IMPORT_ARRAY
3878
- #define PY_ARRAY_UNIQUE_SYMBOL cool_ARRAY_API
3879
- #include numpy/arrayobject.h
3880
-
3881
- You can also put the common two last lines into an extension-local
3882
- header file as long as you make sure that NO_IMPORT_ARRAY is
3883
- #defined before #including that file.
3884
-
3885
- Internally, these #defines work as follows:
3886
-
3887
- * If neither is defined, the C-API is declared to be
3888
- ``static void** ``, so it is only visible within the
3889
- compilation unit that #includes numpy/arrayobject.h .
3890
- * If :c:macro: `PY_ARRAY_UNIQUE_SYMBOL ` is #defined, but
3891
- :c:macro: `NO_IMPORT_ARRAY ` is not, the C-API is declared to
3892
- be ``void** ``, so that it will also be visible to other
3893
- compilation units.
3894
- * If :c:macro: `NO_IMPORT_ARRAY ` is #defined, regardless of
3895
- whether :c:macro: `PY_ARRAY_UNIQUE_SYMBOL ` is, the C-API is
3896
- declared to be ``extern void** ``, so it is expected to
3897
- be defined in another compilation unit.
3898
- * Whenever :c:macro: `PY_ARRAY_UNIQUE_SYMBOL ` is #defined, it
3899
- also changes the name of the variable holding the C-API, which
3900
- defaults to ``PyArray_API ``, to whatever the macro is
3901
- #defined to.
3989
+ Miscellaneous
3990
+ -------------
3902
3991
3903
3992
Checking the API Version
3904
3993
~~~~~~~~~~~~~~~~~~~~~~~~
0 commit comments