如何导入 pybind11 生成的二进制模块?

How to import a binary module generated by pybind11?

我第一次尝试按照 tutorial documentation.

使用 pybind11

如文档所述,我创建了以下 example.cpp 文件,其中包含以下内容:

#include <pybind11/pybind11.h>

int add(int i, int j) {
    return i + j;
}

PYBIND11_MODULE(example, m) {
    m.doc() = "pybind11 example plugin"; // optional module docstring

    m.def("add", &add, "A function which adds two numbers");
}

因为我在 macOS 上,基于 this tutorial,我使用以下命令编译了示例文件:(不确定这是否正确但似乎有效)

c++ -O3 -Wall -shared -std=c++11 -undefined dynamic_lookup -I /usr/local/Cellar/pybind11/2.4.3/include example.cpp -o example`python3-config --extension-suffix --includes`

此命令在同一目录中生成 example.cpython-37m-darwin.so 文件。

然后我创建了 example.py,内容如下:

import example
example.add(1, 2)

但是当我 运行 带有 python example.py 的脚本时,它显示以下错误:

Traceback (most recent call last):
  File "example.py", line 1, in <module>
    import example
  File "/Users/cuinjune/pybind11/build/example.py", line 2, in <module>
    example.add(1, 2)
AttributeError: 'module' object has no attribute 'add'

出了什么问题,如何解决?


编辑:以前,它以某种方式生成了 example.pyc 文件,但我不知道该文件是如何生成的,现在它只是说:ImportError: No module named example.

这一行:

/Users/cuinjune/pybind11/build/example.py

说在你的工作目录中有(或曾经有)另一个文件(或者 /Users/cuinjune/pybind11/build 在你的 PYTHONPATH 中)是一个纯 Python 文件,与你建造的 example.cpython-37m-darwin.so。当导入 example.py 时,大概是在过去的某个时间,生成了您看到的 example.pyc.pyc 保持完整的独立功能,即使原始 example.py 已被删除。 .pyc 文件将在其中硬编码原始文件的完整目录,因此将继续引用该文件,即使它已被删除。

根据你的更新,现在所有其他 example.py.pyc.pyo 都消失了,对吗?

首先确保您 python 的解释器 运行 与您用来构建的标签相匹配。例如 运行:

python3 -c 'import distutils.sysconfig as ds; print(ds.get_config_var("EXT_SUFFIX"))'

(我假设您使用 python3 作为启动 Python 解释器的命令;如果没有,则将其更改为相关命令)。

其次,验证 PYTHONPATH envar 以查看本地目录(完整拼写或 .)是否在其中。如果没有,请添加。

有了这两个,应该可以了...

然而,就我个人而言,我首先会通过将模块重命名为更独特的东西来简化我的生活(重命名 .cpp 中的 example 以及 CLI 中的目标)。