Pybind11 - PYBIND11_MODULE的放置位置

时间:2018-04-25 18:12:30

标签: c++ pybind11

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

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

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

Test.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;
};

Test.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;
}

的main.cpp

#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.然而,这导致链接器错误,该错误表示&#34; _PyInit_TestModule&#34;已在main.obj中定义(MSVS2017错误:LNK2005)

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

你们中有一个人遇到过同样的问题,你们是如何解决的?

1 个答案:

答案 0 :(得分:0)

我为绑定创建了自己的文件,并将其与原始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-binding用python编写主体

5)在您的 main.py

 import PyTest
 # do something