0

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

我目前在做什么

我正在尝试使用 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 imp\n"
        "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 "Pybind\include\pybind11\pybind11.h"
#include "Pybind\include\pybind11\eval.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 imp\n"
        "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;
    }

}
4

1 回答 1

0

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

但是,我不确定这是否是最好的解决方案。也许在同一模块中具有静态成员的不同类?

于 2018-01-25T23:50:03.210 回答