PYBIND11_PLUGIN已有正文

PYBIND11_PLUGIN Already has a body

本文关键字:正文 PLUGIN PYBIND11      更新时间:2023-10-16

我有一个问题,需要帮助找到解决方案。

我目前在做什么

我试图使用PyBind11将几个变量从C++发送到Python(然后用于记录sql数据,但这不是重点)。我将使用以下过程来完成此操作:

SQL_Service.cpp:

namespace py = pybind11;
PYBIND11_PLUGIN(sqlserv)
{
py::module m("sqlserv", "pybind11 sql plugin");
m.attr("bet_player") = BET_PLAYER;
m.attr("total_winnings") = TOTAL_WINNINGS;
return m.ptr();
}
py::object import(const std::string& module, const std::string& path, py::object& globals)
{
py::dict locals;
locals["module_name"] = py::cast(module);
locals["path"] = py::cast(path);
py::eval<py::eval_statements>(
"import impn"
"new_module = imp.load_module(module_name, open(path), path, ('py', 'U', imp.PY_SOURCE))n",
globals,
locals);
return locals["new_module"];
}
int SQL_Service::Log_SQL()
{
try
{
Py_Initialize();
pybind11_init();
py::object main = py::module::import("__main__");
py::object globals = main.attr("__dict__");
py::object module = import("sqlserv", "py_sql_service.py", globals); //name of the python file used
return 0;
}
catch (const py::error_already_set&)
{
std::cerr << ">>> Error! Uncaught exception:n";
PyErr_Print();
return 1;
}
}

这一切都很好,我能够将这两个变量(bet_player和total_winnings)放入python并进行处理。

我想创建另一个"PYBIND11_PLUGIN(somethingelse)",它使用不同的变量并与不同的python脚本关联。

当我试图定义另一个PYBIND11_PLUGIN时会出现问题。即:

namespace py = pybind11;
PYBIND11_PLUGIN(sqlserv)
{
py::module m("sqlserv", "pybind11 sql plugin");
m.attr("bet_player") = BET_PLAYER;
m.attr("total_winnings") = TOTAL_WINNINGS;
return m.ptr();
}
PYBIND11_PLUGIN(somethingelse)
{
py::module m("somethingelse", "pybind11 sql plugin");
m.attr("bet_player2") = BET_PLAYER2;
m.attr("total_winning2s") = TOTAL_WINNINGS2;
return m.ptr();
}

//This gives me the following error
Error   C2084   function 'PyObject *pybind11_init(void)' already has a body 

我希望实现的目标

我想使用我的类(SQL_Service)来定义各种函数,这些函数将从程序中的其他地方接收数据,并打包发送到不同的python脚本,每个脚本只获得所需的数据。(请参阅下面完整示例中的Process_Baccarat(…){…})。

是什么绊倒了我

我依赖于各种教程,这些教程提供了一些小代码片段,或者演示了使用PyBind进行操作的稍微不同的方法。因此,我真的不知道如何得到我想要的东西。

我不确定它是名称空间,或者我只是不能拥有其中的两个函数。也许还有另一种方法可以完全解决这个问题,那会更好。

我也不太高兴不得不使用全局变量(同样,我有一些命名空间混乱),所以如果有一种方法可以很好地完成这一切,那就是我想要的。工作示例代码将不胜感激。

以下是我的完整(工作)SQL_Service.cpp文件供参考:

#include "SQL_Service.hpp"
#include "Pybindincludepybind11pybind11.h"
#include "Pybindincludepybind11eval.h"
#include <string>
#include <iostream>

//G_VARS
int BET_PLAYER = 0;
int TOTAL_WINNINGS = 0;

SQL_Service::SQL_Service()
{
}
SQL_Service::~SQL_Service()
{
}
namespace py = pybind11;
PYBIND11_PLUGIN(sqlserv)
{
py::module m("sqlserv", "pybind11 sql plugin");
m.attr("bet_player") = BET_PLAYER;
m.attr("total_winnings") = TOTAL_WINNINGS;
return m.ptr();
}

py::object import(const std::string& module, const std::string& path, py::object& globals)
{
py::dict locals;
locals["module_name"] = py::cast(module);
locals["path"] = py::cast(path);
py::eval<py::eval_statements>(
"import impn"
"new_module = imp.load_module(module_name, open(path), path, ('py', 'U', imp.PY_SOURCE))n",
globals,
locals);
return locals["new_module"];
}
//I Want to make all sorts of different kinds of these functions.
void SQL_Service::Process_Baccarat(int bet_player, int total_winnings)
{
BET_PLAYER = bet_player;
TOTAL_WINNINGS = total_winnings;
Log_SQL();
}
//And more of these too, if needed.
int SQL_Service::Log_SQL()
{
try
{
Py_Initialize();
pybind11_init();
py::object main = py::module::import("__main__");
py::object globals = main.attr("__dict__");
py::object module = import("sqlserv", "py_sql_service.py", globals); //name of the python file used
return 0;
}
catch (const py::error_already_set&)
{
std::cerr << ">>> Error! Uncaught exception:n";
PyErr_Print();
return 1;
}
}

您需要将PYBIND11_PLUGIN放在单独的编译单元中。在您的情况下,这意味着将代码分为:sqlserv.cppsomethingelse.cpp

然而,我不确定这是否是最好的解决方案。可能是同一模块中有静态成员的不同类?