cppyy 顶层#
cppyy
在模块级别提供了一些辅助函数,这些函数提供(直接)访问 Cling 解释器的功能(任何 C++ 代码总是通过全局命名空间 cppyy.gbl
访问)。文档中会频繁使用这些辅助函数,因此它们首先在这里列出,但通过 Python 解释器本身使用 help()
函数可以更方便地访问它们的文档。
import cppyy
help(cppyy)
Help on package cppyy:
NAME
cppyy - Dynamic C++ bindings generator.
DESCRIPTION
This module provides dynamic bindings to C++ through Cling, the LLVM-based C++
interpreter, allowing interactive mixing of Python and C++. Example:
>>> import cppyy
>>> cppyy.cppdef("""
... class MyClass {
... public:
... MyClass(int i) : m_data(i) {}
... int m_data;
... };""")
True
>>> from cppyy.gbl import MyClass
>>> m = MyClass(42)
>>> cppyy.cppdef("""
... void say_hello(MyClass* m) {
... std::cout << "Hello, the number is: " << m->m_data << std::endl;
... }""")
True
>>> MyClass.say_hello = cppyy.gbl.say_hello
>>> m.say_hello()
Hello, the number is: 42
>>> m.m_data = 13
>>> m.say_hello()
Hello, the number is: 13
>>>
For full documentation, see:
https://cppyy.readthedocs.io/
PACKAGE CONTENTS
__pyinstaller (package)
_cpython_cppyy
_pypy_cppyy
_pythonization
_stdcpp_fix
_typemap
_version
interactive
ll
numba_ext
reflex
types
SUBMODULES
py
FUNCTIONS
add_autoload_map(fname)
Add the entries from a autoload (.rootmap) file to Cling.
add_include_path(path)
Add a path to the include paths available to Cling.
add_library_path(path)
Add a path to the library search paths available to Cling.
c_include(header)
Load (and JIT) header file <header> into Cling.
cppdef(src)
Declare C++ source <src> to Cling.
cppexec(stmt)
Execute C++ statement <stmt> in Cling's global scope.
include(header)
Load (and JIT) header file <header> into Cling.
load_library(name)
Explicitly load a shared library.
macro(cppm)
Attempt to evalute a C/C++ pre-processor macro as a constant
multi(*bases)
Resolve metaclasses for multiple inheritance.
set_debug(enable=True)
Enable/disable debug output.
sizeof(tt)
Returns the storage size (in chars) of C++ type <tt>.
typeid(tt)
Returns the C++ runtime type information for type <tt>.
DATA
__all__ = ['cppdef', 'cppexec', 'macro', 'include', 'c_include', 'load...
__warningregistry__ = {'version': 16}
nullptr = nullptr
VERSION
3.1.2
AUTHOR
Wim Lavrijsen <WLavrijsen@lbl.gov>
FILE
/media/pc/data/lxw/envs/anaconda3x/envs/xxx/lib/python3.12/site-packages/cppyy/__init__.py
/media/pc/data/lxw/envs/anaconda3x/envs/xxx/bin/python3.12: not an ELF file.
cppyy 加载 C++#
C++ 代码可以作为文本加载并即时编译(JIT),或者提前编译并以共享库的形式提供。在后一种情况下,还需要加载 C++ 头文件以向 Cling 声明类、函数和变量。除了头文件,还可以使用预编译代码;特别是所有标准 C++ 头文件和一些系统头文件在启动时都已预编译。cppyy
提供了以下辅助工具来加载 C++ 代码:
cppdef
: 直接访问解释器。此函数接受 C++ 声明作为字符串并即时编译(JIT)它们(在实际使用之前不会创建绑定)。代码被加载到全局范围内,因此从一个cppdef
调用到下一个调用,任何先前加载的代码以及所有已通过预编译头文件加载的标准 C++ 头文件都是可用的。示例:
cppyy.cppdef(r"""\
void hello() {
std::cout << "Hello, World!" << std::endl;
}""")
True
cppyy.gbl.hello()
Hello, World!
cppexec
: 直接访问解释器。此函数接受 C++ 语句作为字符串,即时编译并执行它们。就像cppdef
一样,执行在全局范围内进行,所有先前加载的代码都是可用的。如果语句是声明,效果与cppdef
相同,但cppexec
也接受可执行的代码行。示例:
cppyy.cppexec(r"""std::string hello = "Hello, World!";""")
True
cppyy.cppexec("std::cout << hello << std::endl;")
Hello, World!
True
include
: 将声明加载到解释器中。此函数接受来自文件的 C++ 声明,通常是头文件。文件通过给定给 Cling 的包含路径来定位。示例:
cppyy.include("vector") # equivalent to "#include <vector>"
True
c_include
: 将声明加载到解释器中。此函数接受来自文件的 C++ 声明,通常是头文件。名称修饰是 C 和 C++ 代码之间的一个重要区别。使用c_include
而不是include
可以防止名称修饰。
load_library
: 将编译好的 C++ 代码加载到解释器中。此函数接受共享库的名称,并将其加载到当前进程中,将所有外部符号暴露给 Cling。库通过给定给 Cling 的加载路径来定位,可以通过“-L
”编译器标志或动态搜索路径环境变量(系统依赖)来实现。任何将符号引入进程的方法(包括常规链接,例如在 C++ 应用程序中嵌入 Python 时)都适合用于暴露符号。作为load_library
的替代方案,例如可以使用ctypes.CDLL
,但该函数并非在所有平台上都支持动态加载路径。
如果在使用上述辅助函数中的任何一个对 C++ 代码进行即时编译(JIT)时发生编译错误,会引发 Python SyntaxError
异常。如果发生编译警告,则会发出 Python 警告。
cppyy 配置 Cling#
当加载模块时,通常方便地为 Cling 添加额外的搜索路径以查找头文件和库(Python 没有标准位置来放置头文件和库,但通常可以根据模块的位置推断出它们的位置,即其 __file__
属性)。cppyy
提供了以下两个辅助函数:
add_include_path
: 为 Cling 添加额外的路径以查找头文件。add_library_path
: 为 Cling 添加额外的路径以查找库。
这两个函数都接受一个字符串(单个路径)或一个列表(用于添加多个路径)。允许使用相对路径,但建议使用绝对路径。
cppyy C++ 语言#
一些 C++ 编译时特性在 Python 中没有等效项。相反,提供了便利函数:
sizeof
: 接受一个代理的 C++ 类型或其名称作为字符串,并返回存储大小(以char
为单位)。typeid
: 接受一个代理的 C++ 类型或其名称作为字符串,并返回 C++ 运行时类型信息(RTTI)。nullptr
: C++NULL
。
cppyy
预处理器#
在 Python 端,预处理器宏(#define
)不可用,因为没有可用的类型信息。然而,它们通常用于常量数据(例如标志或数字;请注意,现代 C++ 推荐使用 const
和 constexpr
)。在限制范围内,表示常量数据的宏可以通过 macro
辅助函数访问。示例:
import cppyy
cppyy.cppdef('#define HELLO "Hello, World!"')
True
cppyy.macro("HELLO")
'Hello, World!'