0

我目前正在玩 pybind11。我试图创建一个 C++ 类,然后将其传递给嵌入在我的 C++ 源代码中的 python 解释器。

我创建了一些虚拟类只是为了测试我将所有内容保存在单个源文件中的基本功能。这种方法编译并运行没有任何问题。

现在我将我的虚拟类Test分成了 Test.h 和 Test.cpp

测试.h

#pragma once
#include<iostream>
#include"pybind11\pybind11.h"

namespace py = pybind11;

class Test
{
public:
    Test(const std::string &s);
    ~Test();

    void printStr();

private:
    std::string _s;
};

测试.cpp

#include "Test.h"

PYBIND11_MODULE(TestModule, m)
{
    py::class_<Test>(m, "Test") 
        .def(py::init<const std::string &>())
        .def("printStr", &Test::printStr); 
}


Test::Test(const std::string &s) : _s(s)
{

}
Test::~Test()
{

}

void Test::printStr()
{
    std::cout << "---> " << _s << std::endl;
}

主文件

#include"Test.h"

int main(int argc, char **argv)
{

    PyImport_AppendInittab("TestModule", PyInit_TestModule);
    Py_Initialize(); 

    PyRun_SimpleString("import TestModule");
    PyRun_SimpleString("t = TestModule.Test(\"str\")"); 
    PyRun_SimpleString("t.printStr()"); 
    Py_Finalize();

    getchar();

    return 1;
}

将类Test放入新文件后,编译器无法再找到PyInit_TestModule(main.cpp 行:6),因为这是由PYBIND11_MODULE位于 Test.cpp 文件中的宏生成的(MSVS2017 错误:C2065)。

我尝试将PYBIND11_MODULE宏放入 Test.h。然而,这导致了一个链接器错误,指出“_PyInit_TestModule”已在 main.obj 中定义(MSVS2017 错误:LNK2005)

PYBIND11_MODULE宏放在 main.cpp 文件中是可行的。但是,我觉得一旦您将大量自定义模块定义放入 main.cpp,这将变得非常难以理解,或者更糟糕的是,您从不同的源文件启动了多个 Python-Interpreter,然后您需要将相同的定义放入所有文件中那些将是一团糟并且很可能变成链接器错误的文件。

你们当中有人遇到过同样的问题吗?你们是如何解决的?

4

1 回答 1

1

我为绑定创建了一个他自己的文件,并将其与原始 c++ 文件一起编译/链接。这边走:

1) Test.h+Test.cpp只包含你的类的 c++ 代码

2)Test-bindings.cpp包含 PYBIND11_MODULE 和#include <Test.h>

3)构建(使用cmake)。你会得到一个PyTest.so文件,你可以在 python 中加载它。

# c++ libray
add_library(TestLib SHARED /path/to/Test.h /path/to/Test.cpp)

# bindings
add_subdirectory(pybind11) # you must have downloaded this repo
include_directories(/path-only/to/Test.h)
pybind11_add_module(PyTest SHARED /path/to/Test-bindings.cpp /path/to/Test.cpp)

4)(我建议你)在python中编写main,使用你刚刚创建的python-binding

5)在你的main.py

 import PyTest
 # do something
于 2018-11-13T13:05:42.230 回答