1

我们正在尝试在我们的 C++ 代码中嵌入几个 Python 过程,但它失败并出现错误

TypeError: No to_python (by_value) converter found for C++ type: boost::python::detail::kwds_proxy

我们诚实地研究了我们设法通过网络找到的所有示例(thisthis ),但是对于****kwargs** 变量从 C++ 传递到 Python,我们仍然没有任何明确的解决方案。这种失败似乎非常罕见。

我们试图调用的 Python 函数接收一个字符串值和一个字典:

from ipalib import api
user_kw = dict(givenname=u'Test', sn=u'User')
api.Command.user_add.(u'Pythonist', **user_kw)

这是它的 C++ 实现:

//Importing modules
bp::import("__main__");
ipalib = bp::import("ipalib");
ipalib_namespace = ipalib.attr("__dict__");
api = ipalib.attr("api");

... //Starting Python environment

//Construct args
std::string name = "Pythonist";
bp::dict new_user;
new_user["givenname"] = "Test";
new_user["sn"] = "User";

//Calling the function
bp::object user_add_wrapper = api.attr("Command").attr("user_add");
user_add_wrapper(name, new_user);

最后一行 Boost 抛出异常。我们做错了什么?谢谢你。

4

1 回答 1

3

user_add_wrapper(name, new_user)尝试new_user作为字典传递给user_add_wrapper(),而不是传递new_user. new_user字典需要解压。此外,python::object使用未打包的字典调用 需要第一个参数是 unpacked boost::python::tuple。为了满足这些要求,调用user_add_wrapper()如下:

user_add_wrapper(*bp::make_tuple(name), **new_user);

这种行为是 Boost.Python 提供的无缝互操作性的一部分,但它相当模糊,我只记得注意到它在更改日志中间接提到,而不是在教程或参考中。


下面是一个完整的最小示例。给定example.py

def user_add(name, givenname, sn):
    print locals()

以下程序user_add()通过解包字典来调用:

#include <boost/python.hpp>

int main()
{
  Py_Initialize(); // Start interpreter.

  // Create the __main__ module.
  namespace python = boost::python;
  python::object main = python::import("__main__");
  python::object main_namespace = main.attr("__dict__");

  try
  {
    python::object example = python::import("example");
    python::object example_namespace = example.attr("__dict__");

    // Construct args.
    std::string name = "Pythonist";
    python::dict new_user;
    new_user["givenname"] = "Test";
    new_user["sn"] = "User";

    // Invoke user_add by unpacking the new_user dictionary.
    example_namespace["user_add"](*python::make_tuple(name), **new_user);
  }
  catch (const python::error_already_set&)
  {
    PyErr_Print();
  }
}

并产生以下输出:

{'givenname': 'Test', 'sn': 'User', 'name': 'Pythonist'}
于 2013-09-19T19:49:57.083 回答