Embedding HPy modules

There might be cases where it is beneficial or even necessary to embed multiple HPy modules into one library. HPy itself already makes use of that. The debug and the trace module do not have individual libraries but are embedded into the universal module.

To achieve that, the embedder will use the macro HPy_MODINIT several times. Unfortunately, this macro defines global state and cannot repeatedly be used by default. In order to correctly embed several HPy modules into one library, the embedder needs to consider following:

  • The modules must be compiled with preprocessor macro HPY_EMBEDDED_MODULES defined to enable this feature.

  • There is one major restriction: All HPy-specific module pieces must be in the same compilation unit. HPy-specific pieces are things like the module’s init function (HPy_MODINIT) and all slots, members, methods of the module or any type of it (HPyDef_*). The implementation functions (usually the *_impl functions) of the slots, members, methods, etc. and any helper functions may still be in different compilation units. The reason for this is that the global state induced by HPy_MODINIT is, of course, made local (e.g. using C modifier static).

  • It is also necessary to use macro HPY_MOD_EMBEDDABLE(module_name) before the first usage of any HPyDef_* macro.

Example

// compile with -DHPY_EMBEDDED_MODULES

HPY_MOD_EMBEDDABLE(hpymodA)

HPyDef_METH(foo, /* ... */)
static HPy foo_impl(/* ... */)
{
    // ...
}

HPy_MODINIT(hpymodA)
static HPy init_hpymodA_impl(HPyContext *ctx)
{
    // ...
}