1

を使用していくつかの Python プロシージャを C++ コードに埋め込もうとしていますが、エラーで失敗します

TypeError: C++ タイプの to_python (by_value) コンバーターが見つかりません: boost::python::detail::kwds_proxy

ネットワーク上で見つけたすべての例 ( thisおよびthis ) を正直に調べましたが、 ****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_usernew_userpython::objectboost::python::tupleuser_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 に答える