HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
pyModule.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifdef PXR_BASE_TF_PY_MODULE_H
8 #error This file should only be included once in any given source (.cpp) file.
9 #endif
10 #define PXR_BASE_TF_PY_MODULE_H
11 
12 #include "pxr/pxr.h"
13 
15 #include "pxr/base/tf/api.h"
17 
18 #include "pxr/external/boost/python/module.hpp"
19 
20 // Helper macros for module files. If you implement your wrappers for classes
21 // as functions named wrapClassName(), then you can create your module like
22 // this:
23 //
24 // TF_WRAP_MODULE(ModuleName) {
25 // TF_WRAP(ClassName1);
26 // TF_WRAP(ClassName2);
27 // TF_WRAP(ClassName3);
28 // }
29 //
30 
31 // Forward declare the function that will be provided that does the wrapping.
32 static void WrapModule();
33 
35 
36 TF_API
37 void Tf_PyInitWrapModule(void (*wrapModule)(),
38  const char* packageModule,
39  const char* packageName,
40  const char* packageTag,
41  const char* packageTag2);
42 
44 void TF_PP_CAT(init_module_, MFB_PACKAGE_NAME)() {
45 
47  WrapModule,
48  TF_PP_STRINGIZE(MFB_PACKAGE_MODULE),
49  TF_PP_STRINGIZE(MFB_ALT_PACKAGE_NAME),
50  "Wrap " TF_PP_STRINGIZE(MFB_ALT_PACKAGE_NAME),
51  TF_PP_STRINGIZE(MFB_PACKAGE_NAME)
52  );
53 }
54 
56 
57 // When we generate boost python bindings for a library named Foo,
58 // we generate a python package that has __init__.py and _Foo.so,
59 // and we put all the python bindings in _Foo.so. The __init__.py
60 // file imports _Foo and then publishes _Foo's symbols as its own.
61 // Since the module with the bindings is named _Foo, the PyInit routine
62 // must be named PyInit_Foo. This little block produces that function.
63 //
64 // See https://docs.python.org/3/c-api/module.html#initializing-c-modules_
65 //
66 extern "C"
68 PyObject* TF_PP_CAT(PyInit__, MFB_PACKAGE_NAME)() {
69 
70  static struct PyModuleDef moduledef = {
71  PyModuleDef_HEAD_INIT,
72  TF_PP_STRINGIZE(TF_PP_CAT(_, MFB_PACKAGE_NAME)), // m_name
73  0, // m_doc
74  -1, // m_size
75  NULL, // m_methods
76  0, // m_reload
77  0, // m_traverse
78  0, // m_clear
79  0, // m_free
80  };
81 
83  return pxr_boost::python::detail::init_module(moduledef,
84  TF_PP_CAT(init_module_, MFB_PACKAGE_NAME));
85 }
86 
87 // We also support the case where both the library contents and the
88 // python bindings go into libfoo.so. We still generate a package named foo
89 // but the __init__.py file in the package foo imports libfoo and
90 // publishes it's symbols as its own. Since the module with the
91 // bindings is named libfoo, the init routine must be named PyInit_libfoo.
92 // This little block produces that function.
93 //
94 // So there are two init routines in every library, but only the one
95 // that matches the name of the python module will be called by python
96 // when the module is imported. So the total cost is a 1-line
97 // function that doesn't get called.
98 //
99 extern "C"
101 PyObject* TF_PP_CAT(PyInit_lib, MFB_PACKAGE_NAME)() {
102 
103  static struct PyModuleDef moduledef = {
104  PyModuleDef_HEAD_INIT,
105  TF_PP_STRINGIZE(TF_PP_CAT(lib, MFB_PACKAGE_NAME)), // m_name
106  0, // m_doc
107  -1, // m_size
108  NULL, // m_methods
109  0, // m_reload
110  0, // m_traverse
111  0, // m_clear
112  0, // m_free
113  };
114 
116  return pxr_boost::python::detail::init_module(moduledef,
117  TF_PP_CAT(init_module_, MFB_PACKAGE_NAME));
118 }
119 
120 
121 #define TF_WRAP_MODULE static void WrapModule()
122 
123 // Declares and calls the class wrapper for x
124 #define TF_WRAP(x) ARCH_HIDDEN void wrap ## x (); wrap ## x ()
#define TF_API
Definition: api.h:23
PXR_NAMESPACE_OPEN_SCOPE TF_API void Tf_PyInitWrapModule(void(*wrapModule)(), const char *packageModule, const char *packageName, const char *packageTag, const char *packageTag2)
#define TF_PP_STRINGIZE(x)
Expand and convert the argument to a string, using a most minimal macro.
#define ARCH_EXPORT
Definition: export.h:164
ARCH_EXPORT void TF_PP_CAT(init_module_, MFB_PACKAGE_NAME)()
Definition: pyModule.h:44
#define PXR_NAMESPACE_USING_DIRECTIVE
Definition: pxr.h:77
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74