Как получить доступ к множественным возвращаемым переменным, скомпилированным в python - PullRequest
0 голосов
/ 06 марта 2019

Я новичок в программировании, я определил функцию в c ++ с методом кортежа для двух возвращаемых переменных, после того как я скомпилировал файлы, В файле python я пытаюсь получить доступ к двум возвращенным переменным внутри динамической библиотеки, которая была скомпилирована , но это не работает, произошла ошибка сегментации, когда я пытался запустить программу python. Но на самом деле я успешно использую одну возвращаемую переменную из c ++, я думаю, что может быть особая хитрость для доступа к двум возвращаемым переменным с помощью метода кортежа из python.

Ниже приведен код C ++ с двумя возвращаемыми переменными с методом кортежа

std::tuple<double, double> Cassie2d::Step(ControllerTorque* action)
{
  dyn_model_.setState(mj_data_->qpos, mj_data_->qvel);
  dyn_state_.UpdateDynamicState(&dyn_model_);

  mju_copy(mj_data_->ctrl, action->torques, nU);
  mj_step(mj_model_, mj_data_);
  return std::make_tuple(mj_data_->qacc,mj_data_->time);
  Render();
}

Ниже приведен метод python, который я применил, поскольку обе возвращаемые переменные имеют тип double.

lib.StepTorque.argtypes = [ctypes.c_void_p, ctypes.POINTER(ControllerTorque)]
lib.StepTorque.restype = ctypes.c_double

Я предполагаю, что restype не просто равен ctypes.c_double, потому что он работал для одной возвращаемой переменной и может не работать для двух возвращаемых переменных.

Очень ценю за помощь!

1 Ответ

0 голосов
/ 06 марта 2019

С return std::make_tuple(mj_data_->qacc,mj_data_->time) вы создаете структуру, которая содержит две переменные, определенные в скобках.Если функция будет вызываться из собственного кода C ++, вы сможете распаковать ее, используя std: tie, eq:

double a, b;
std::tie(a,b) = Step(arg);

Однако вам нужно вызывать ее напрямую из python, который имеет совершенно другой синтаксис для возвратамножественные переменные (пара или кортеж C ++ является своего рода обходом отсутствующей функциональности).Я вижу два варианта в Python.

  1. Дайте вашей функции C ++ два обратных вызова для Python и отправьте переменные отдельно таким образом:

    void Cassie2d::Step(ControllerTorque* action, callback1, callback2)
    {
    dyn_model_.setState(mj_data_->qpos, mj_data_->qvel);
    dyn_state_.UpdateDynamicState(&dyn_model_);
    
    mju_copy(mj_data_->ctrl, action->torques, nU);
    mj_step(mj_model_, mj_data_);
    callback1(mj_data_->qacc);
    callback2(mj_data_->time);
    Render();
    }
    
  2. (Рекомендуется). Вы можете попытаться использовать встроенную опцию Python для обслуживания множественного возврата.Оставив вам функцию C ++ в ее первоначальном виде и вызовите в python следующим образом:

    VarA, VarB = Step(action)
    

    Я предполагаю, что в вашем коде Python есть ссылка на метод Cassie2d::Step(ControllerTorque* action), однако вы предоставили очень маленький фрагмент.

...