【问题标题】:What are the next step after compiling PYBIND11_MODULE in C++ file在 C++ 文件中编译 PYBIND11_MODULE 之后的下一步是什么
【发布时间】:2020-11-13 04:18:54
【问题描述】:

我试图使用 PYbind 11 将以下小型 C++ 测试程序包装到 Python 模块中,这样我就可以从 python 文件中调用测试 C++ 函数。 我的问题是:虽然 C++ 文件编译成功,但我不知道下一步要采取什么步骤在 python 中导入新创建的模块文件。 我试图在 Spyder 的测试 Python 文件中运行“从示例导入添加”,但收到错误消息说没有名为示例的模块。 我正在使用 Windows10 (x64bit)、Python3.7 和 Visual Studio 2017 社区。 有人可以帮忙吗?非常感谢!

#include
//#include <Aspose.Cells.h>
#include <pybind11/pybind11.h>

void print(const char*);

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");
}

int main()
{
const char *x = "C Plus plus is wonderful.";

char *z;
char b = 'z';
z = &b;

int num = 10;
int* a = 0;

print(x);
}

void print(const char* z)
{

std::cout << "pointer z is" << z << "\n";

std::cin.get();
}

更新:在构建我的测试 C++ 程序时,我遵循了以下 Stuart 的建议。我做了两次尝试:第一次尝试时,我将 Target Extension 更改为“.pyd”;而在第二次尝试时,我将 Target Extension 保留为“dll”。

在两次尝试中,我都收到了来自 Visual Studio 的相同错误消息,这似乎表明正在构建的 DLL 文件无法启动(如紧随其后的屏幕截图所示) Error Messages for Starting DLL Programme 但是,实际构建 dll 文件似乎是成功的,因为我可以看到一个 dll 文件和一个 Python 扩展模块文件,文件名和路径如下所示: C:\Users\rmili\source\repos\ConsoleApplication5\x64\Debug\ConsoleApplication5.dll 和 C:\Users\rmili\source\repos\ConsoleApplication5\x64\Debug\ConsoleApplication5

构建时的 Visual Studio 输出消息粘贴在末尾。

我的问题是:我在同一个目录(C:\Users\rmili\source\repos\ConsoleApplication5\x64\Debug)中创建了一个Test.py文件 并尝试在仅包含一行命令“导入示例”后在 Spyder 中运行它。 Sypder 返回了一条错误消息,说“没有 MODULE Named Example”。

有人可以帮忙吗?非常感谢!

1>------ Build started: Project: ConsoleApplication5, Configuration: Debug x64 ------
1>LINK : C:\Users\rmili\source\repos\ConsoleApplication5\x64\Debug\ConsoleApplication5.dll not found or not built by the last incremental link; performing full link
1>   Creating library C:\Users\rmili\source\repos\ConsoleApplication5\x64\Debug\ConsoleApplication5.lib and object C:\Users\rmili\source\repos\ConsoleApplication5\x64\Debug\ConsoleApplication5.exp
1>ConsoleApplication5.vcxproj -> C:\Users\rmili\source\repos\ConsoleApplication5\x64\Debug\ConsoleApplication5.dll
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

UPDATE2:我按照 Stuart 在他的 Update2 中的说明进行了每一个细节。 我得到了 example.pyd(如以下屏幕截图所示) 但是,我在 Spyder 中运行时收到错误消息,如下所示: (对不起,我只复制了 Spyder 输出消息的后半部分,因为它很难在 Spyder 控制台中进行文本选择)

File "C:\Users\rmili\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 110, in execfile
    exec(compile(f.read(), filename, 'exec'), namespace)

  File "C:/Users/rmili/source/repos/ConsoleApplication5/x64/Debug/Test.py", line 9
    d = "C:\Users\rmili\source\repos\ConsoleApplication5\x64\Debug"
       ^
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \UXXXXXXXX escape

我将分配给“d”的值中的反斜杠“”更改为正斜杠“/”,并再次收到以下错误:

File "C:\Users\rmili\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 110, in execfile
    exec(compile(f.read(), filename, 'exec'), namespace)

  File "C:/Users/rmili/source/repos/ConsoleApplication5/x64/Debug/Test.py", line 12, in <module>
    import example

ModuleNotFoundError: No module named 'example'

更新3: 如以下屏幕截图所示,在 Windows 命令行提示符下找不到示例模块。 [Unable to find example module in Windowscommand line prompt]3

【问题讨论】:

    标签: python c++ c build pybind11


    【解决方案1】:

    确保编译后的输出文件名为example.pyd(或具有指向该名称的符号链接),并尝试从同一目录运行python。


    更新:如何在 Visual Studio 中构建 .pyd

    在 Windows 上,已编译的 Python 模块只是 DLL 文件,但它们具有 .pyd 文件扩展名。您提到您的 C++ 文件编译成功。你是编译成可执行文件(.exe)还是.dll?您应该将其编译为 DLL,但将文件扩展名更改为 .pyd

    Visual Studio 文档explains how to change your project to create a DLL。它是这样说的:

    1. 打开项目的“属性页”对话框。详情见Set C++ compiler and build properties in Visual Studio.

    2. 单击配置属性文件夹。

    3. 单击“常规”属性页。

    4. 修改配置类型属性。

    此外,在同一设置页面上,您可以找到更改Target Extension 属性的选项。将其更改为.pyd。 (或者只是在构建文件后自己重命名文件。)


    更新 2

    我认为你需要更改三个设置:

    • Target Name
      • 更改为example
    • Target Extension
      • 更改为.pyd
    • Configuration Type
      • 更改为Dynamic Library (.dll)

    此外,我建议删除(或注释掉)example.cpp 中的所有内容,但下面显示的代码除外。 (不知道main()函数的存在会不会导致问题,所以去掉就好了。)

    之后,构建您的项目应生成以下文件:

    C:\Users\rmili\source\repos\ConsoleApplication5\x64\Debug\example.pyd

    然后,从 Spyder 控制台试试这个:

    import os
    
    d = "C:\\Users\\rmili\\source\\repos\\ConsoleApplication5\\x64\\Debug"
    os.chdir(d)
    
    import example
    example.add(1,2)
    

    我没有要测试的 Windows 机器。但如果它有用,下面是我在 Mac 上编译您的示例的方式。 (在 Mac 和 Linux 上,它们使用扩展名 .so 而不是 .pyd。)

    // example.cpp
    #include <pybind11/pybind11.h>
    
    int add(int i, int j) {
        return i + j;
    }
    
    PYBIND11_MODULE(example, m) {
        m.doc() = "pybind11 example plugin";
    
        m.def("add", &add, "A function which adds two numbers");
    }
    
    $ # Compile
    $ clang++ -I${CONDA_PREFIX}/include -I${CONDA_PREFIX}/include/python3.7m -undefined dynamic_lookup -shared -o example.so example.cpp
    
    $ # Test
    $ python -c "import example; print(example.add(10,20))"
    30
    

    【讨论】:

    • 感谢您的回复。我不确定如何确保在某个扩展名(例如 pyd)中生成输出文件。它是否需要安装一些其他库,例如 setuptools 或 Cmake ?谢谢。
    • 我已经添加了一些关于如何在 Visual Studio 项目中执行此操作的说明。请参见上文。
    • 嗨 Stuart,我按照您的指示进行了尝试。我想我得到了 Python 扩展模块文件,但遗憾的是,当我尝试在 Spyder 中运行它时,我仍然无法让我的 test.py 文件导入它。我在我最初的帖子的更新中描述了故事的细节。你能看看吗?非常感谢!
    • 请参阅上面的更新 2。
    • 嗨斯图尔特谢谢你的回复。我已经在 update2 中尝试了您的说明,但遇到了不同的错误,这次是来自 Spyder。我也在我的 Update2 中描述了它。可以看看吗,非常感谢!
    【解决方案2】:

    我找到了问题的答案:

    1. 确保我之前在帖子中描述的所有步骤都已完成
    2. 这是我错过的 -` 确保“示例”的文件类型是 Python 扩展模块很重要,如以下屏幕截图 所示。 如我的更新截图所示,最初我的“example.pyd”文件的类型只是“文件”。我设法通过添加“cp35-win_amd64”将其转换为 Python 扩展模块。在文件扩展名中,生成文件名“examplelib.cp35-win_amd64.pyd”,然后删除添加的相同文本。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-13
      • 2011-10-27
      • 2017-06-04
      • 2020-05-04
      • 2011-06-17
      相关资源
      最近更新 更多