コンテキストは埋め込まれたpythonスクリプトのもので、C++で書かれたコードからインタープリタ を呼び出しています。ラッパーからベクトルのマップへの抽出
C++とPythonの以下のコード二つの最も一般的なSTLコンテナ、C++でラップPythonで使用し、C++でバック抽出する手法を要約:
- のstd ::ベクトル
- STDを:: map
特に、std :: string型要素を保持する場合に焦点を当てています。
ブースト・イテレータと反復可能スイートは、両方の言語に共通する概念にマッピングされていますが、2つのプログラミング環境ではかなり異なって扱われています。
私は、既存の材料や個人実験をもとに、最も一般的な用途に意図された方法であると思われるものを明らかにしました。他の場所では表示されていないものはありませんが、boost :: pythonは例と説明のケースで冗長性を少しでも許しているように感じます。
これまで解決できないようなケースが1つあります。文字列のラップベクターをC++に戻すことです。誰かが私にこのことを教えてもらえると感謝しています。
このコードは自己完結型であり、2つの目的を果たします。まず、自分のように、シンプルなユースケースの例を探している人を助けるためのものです。また、doubleのベクトルの操作は、ベクトル文字列よりも簡単です。
以下のC++の例では、本質的に実行時エラーが発生します。 typedef std :: vector VecStr; class boost :: python :: class> struct boost :: python :: deltail :: not_specified_strucこのtypeMapStringVectorStringのPythonオブジェクトから。
ご迷惑をおかけして申し訳ございません。
PS:メモリから修正されたコードを再構築しなければならず、構文エラーが発生する可能性があります。私は接続されたマシンにアクセスするとすぐにそれらを修正します。
#include "stdafx.h"
#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <boost/python/suite/indexing/map_indexing_suite.hpp>
#include <Python.h>
#include <string>
#include <iostream>
#include <vector>
using namespace std;
using namespace boost::python;
BOOST_PYTHON_MODULE(idctor)
{
typedef std::vector<string> VectorString;
typedef std::map<string, VectorString> MapVectorString;
typedef class_<VectorString, shared_ptr<VectorString>> pyVectorString;
using namespace boost::python;
class_<std::vector<double> >("DoubleVector")
.def(vector_indexing_suite<std::vector<double> >());
class_<std::vector<std::string>,shared_ptr<VectorString> >("VectorString")
.def(vector_indexing_suite<std::vector<string> >());
class_<std::map<std::string, double> >("StringDoubleMap")
.def(map_indexing_suite<std::map<std::string, double> >());
class_<std::map<string, string> >("MapStringString")
.def(map_indexing_suite<std::map<std::string, string> >());
class_<std::map<string, VectorString> , shared_ptr<MapVectorString>>("MapStringVectorString")
.def(map_indexing_suite<std::map<std::string, VectorString> >());
}
typedef std::vector<string> VectorString;
typedef class_<VectorString> pyVectorString;
typedef class_<VectorString, shared_ptr<VectorString>> pyMapVectorString;
int main()
{
PyImport_AppendInittab("idctor", &PyInit_idctor);
Py_Initialize();
try {
//PyInit_hello();
object main
= object(handle<>(borrowed(PyImport_AddModule("__main__"))));
object main_namespace = main.attr("__dict__");
PyRun_SimpleString("import sys\n");
exec_file("G:\\Developments\\VisualStudio\\BoostPythonSTLContainers\\stlcontainers.py", main_namespace);
// Getting back an Python object containing a
// vector of double, extracting the
// corresponding typed C++ object and using it
object pyv = main_namespace["v"];
//----------------> this works <--------------
std::vector<double>& v = extract<vector<double>&>(pyv);
v.push_back(665);
//----------------> this does not <----------------
// Getting back a working Python object
object pyvs = main_namespace["vs"];
// Attempting to convert it back to its true C++ type
// Here the conversion fails:
VectorString& vs = extract<VectorString&>(pyvs);
vs.push_back("not yet the beast");
// Attempt to do the same with a map of string to vector of strings
object pymvs = main_namespace["mvs"];
//----------------> Clearly this fails too <--------------
pyMapVectorString& mvs = extract<pyMapVectorString&>(pymvs);
object pyvs = mvs["this "];
VectorString& vs = extract<VectorString&>(pyvs);
vs.push_back({ "should ","work" });
}
catch (error_already_set) {
PyErr_Print();
return 1;
}
Py_Finalize();
return 0;
}
、ここで(作業)のpythonのコードです:
#
# All the python code below is working fine
# (the issue is converting back in C++)
import idctor
#defining a function to print a container
def tostr(container):
string ='['
for i in container:
string += str(i)+","
string+='end]'
return string
# Turning it into a instance method
idctor.DoubleVector.__str__ = tostr
# instantiating a vector of doubles
v = idctor.DoubleVector()
v.append(1.0)
v.append(2.0)
for i in v:
print(i)
#instantiating a vector of strings
idctor.VectorString.__str__ = tostr
vs = idctor.VectorString()
vs.append("he2")
vs.append("he1")
print("Directly: ", vs)
for s in vs:
print(s)
m = idctor.StringDoubleMap()
# instantiating a map of string to doubles
m["a"] = 1
m["b"] = 2
for i in m:
print(i)
print(m)
#instantiating a map of string to strings
ms = idctor.MapStringString()
ms["a"]="he1"
ms["b"]="he2"
for s in ms:
print(s)
#instantiating a map of string to vectors of strings
mvs = idctor.MapStringVectorString()
mvs["a"]=vs
vs2=idctor.VectorString()
vs2.append("cy")
vs2.append("ve")
mvs["b"]=vs2
for vs in mvs:
print(vs)
「冗長でかなり致命的なエラー」あなたはあなたの質問にそれを含めるべきです。 –