我目前正在玩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
需要在所有那些混乱的文件中加入相同的定义,最有可能变成链接器错误。
你们中有一个人遇到过同样的问题,你们是如何解决的?
答案 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