Ich habe eine Warteschlange von Objekten, die ich aus der Warteschlange nehme, um ein Objekt zu erhalten und es in Python zu verarbeiten, bevor das Ergebnis zurückgegeben wird. Ich bin ein bisschen unsicher, wie das alles zusammenpasst, aber von dem, was ich an verschiedenen Orten gesammelt habe, denke ich, bin ich ziemlich nah dran.C++ - Objektinstanz an Python-Funktion übergeben
Ich habe eine Klasse, die wie folgt aussieht:
class PyData
{
public:
PyData(
const btVector3 &TORSO_LV,
std::vector<std::tuple<float, float, float>> DsOsAVs,
std::vector<btVector3> RF_FORCES,
std::vector<btVector3> LF_FORCES,
float slope,
float compliance
);
std::tuple<float, float, float> m_TORSO_LV;
std::vector<std::tuple<float, float, float>> m_DsOsAVS;
std::vector<std::tuple<float, float, float>> m_RF_FORCES;
std::vector<std::tuple<float, float, float>> m_LF_FORCES;
float m_slope;
float m_compliance;
~PyData();
};
und dann erstelle ich einen Schub Python-Modul, das wie folgt aussieht:
BOOST_PYTHON_MODULE(pydata) {
bp::class_<PyData>("PyData",
bp::init<
const btVector3,
std::vector<std::tuple<float, float, float>>,
std::vector<btVector3>,
std::vector<btVector3>,
float,
float
>())
.def_readonly("Torso_LV", &PyData::m_TORSO_LV)
.def_readonly("DsOsAVs", &PyData::m_DsOsAVS)
.def_readonly("RF_FORCES", &PyData::m_RF_FORCES)
.def_readonly("LF_FORCES", &PyData::m_LF_FORCES);
};
Nach jeweils 33 ms Ich erstelle ein PyData Objekt und Legen Sie es in die Warteschlange. Etwas wie folgt aus:
// Check the sample clock for sampling
if (m_sampleClock.getTimeMilliseconds() > 33) {
if (ContactManager::GetInstance().m_beingUsed) {
PyData dat = BuildPyData();
if (dat.m_compliance != 0.0f) {
std::unique_lock <std::mutex> l(m_mutex);
m_data.push_front(dat);
m_NotEmptyCV.notify_one();
l.unlock();
}
}
m_sampleClock.reset();
}
ich dann einen separaten Arbeitsthread haben, der die Warteschlange aus der Warteschlange entfernt, ein Objekt zu erhalten und senden Sie es an eine Python-Funktion aus, die wie folgt aussieht: Im Grunde genommen
void ContactLearningApp::PythonWorkerThread() {
printf("Start Python thread. \n");
bp::object f = m_interface.attr("predict_on_data");
while (true) {
//printf("Inside while loop and waiting. \n");
std::unique_lock<std::mutex> ul(m_mutex);
while (m_data.size() <= 0) {
m_NotEmptyCV.wait(ul);
}
PyData dat = m_data.back();
m_data.pop_back();
f(boost::python::ptr(&dat));
ul.unlock();
//m_ProcessedCV.notify_one();
//bp::exec("print ('Hello from boost')", m_main_namespace);
}
}
, Ich versuche, ein in C++ instanziiertes Objekt als Python-Argument übergeben, aber ich bin mir nicht sicher, wie ich es zusammensetzen soll. Der Python-Interpreter benötigt keine Kopie des Objekts, daher verwende ich boost :: python :: ptr. Die Python-Datei ist einfach und ich möchte nur auszudrucken das Objekt auf die Konsole wie folgt erhalten:
def predict_on_data(data):
print("In Predict on Data")
print(data)
Ich bin nicht sicher, wie das mit dem Boost-Modul integriert. Was wäre der richtige Weg, dies zu tun?
Ich kann nicht finden, initpydata() -Funktion zu finden. Ich weiß, dass es automatisch generiert wird, da die Dokumentation sagt, dass es initname() und init_module_name() generiert. Ich kann init_module_pydata() finden. Sind sie das Gleiche? Es sieht so aus, als ob init_name nur init_module_name an handle_exception() in C++ übergibt. – terminix00
Im C++ Code in meinem Beispiel wird die initpydata() - Funktion (über Makro) erstellt und durch den Code-Block, der mit BOOST_PYTHON_MODULE (pydata) beginnt, in den Gültigkeitsbereich gebracht - haben Sie das in Ihrem Code? Wenn ja, sollte es da sein. –