PYBIND11_PLUGIN已经有一个正文

时间:2017-02-02 18:03:27

标签: python c++ pybind11

我遇到了问题,我需要帮助才能找到解决方案。

我目前正在做什么

我试图使用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中并处理它们。

我想创建另一个&#34; PYBIND11_PLUGIN(somethingelse)&#34;关联使用不同的变量,并与不同的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;
    }

}

1 个答案:

答案 0 :(得分:0)

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

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