#python #c #segmentation-fault #stdtuple #ctype
#python #c #ошибка сегментации #ctypes #стандартный набор
Вопрос:
Я новичок в программировании, я определил функцию на c с помощью метода tuple для двух возвращаемых переменных, после того, как я скомпилировал файлы В файле python, я пытаюсь получить доступ к двум возвращаемым переменным внутри динамической библиотеки, которые были скомпилированы, но это не работает, при попытке запустить программу python произошла ошибка сегментации. Но я действительно добился успеха с одной возвращаемой переменной из c , я думаю, что может быть специальный трюк для доступа к двум возвращаемым переменным с помощью метода tuple из python.
Ниже приведен код c с двумя возвращаемыми переменными с помощью метода tuple
std::tuple<double, double> Cassie2d::Step(ControllerTorque* action)
{
dyn_model_.setState(mj_data_->qpos, mj_data_->qvel);
dyn_state_.UpdateDynamicState(amp;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, который я применил, поскольку обе возвращаемые переменные имеют двойной тип.
lib.StepTorque.argtypes = [ctypes.c_void_p, ctypes.POINTER(ControllerTorque)]
lib.StepTorque.restype = ctypes.c_double
Я предполагаю, что restype
это не просто равно ctypes.c_double
, потому что это сработало для одной возвращаемой переменной и может не сработать для двух возвращаемых переменных.
Очень признателен за помощь!
Комментарии:
1. Предоставьте некоторые подробности — какую библиотеку python вы используете? Ошибка сегментации предполагает, что вы можете инициализировать python, но не некоторые дополнительные модули (возможно, numpy?). К нескольким возвращаемым переменным обычно можно получить доступ следующим образом:
VarA, VarB = function_name(arguments)
2. lib = cdll. LoadLibrary(‘../../bin/libcassie2d.so’). Файл c , скомпилированный в динамическую библиотеку, которая libcassie2d.so приведенный выше код загружает библиотеку на python, я мог бы загрузить одну возвращаемую переменную, а не две переменные, которые я определил в c
3.
ctypes
предназначен для C , а не C . Он не понимает классы C и нуждается в стандартных типах C, таких какdouble
, notstd::tuple<double, double>
.
Ответ №1:
С 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.
-
Дайте вашей функции C два обратных вызова в python и отправляйте переменные отдельно таким образом:
void Cassie2d::Step(ControllerTorque* action, callback1, callback2) { dyn_model_.setState(mj_data_->qpos, mj_data_->qvel); dyn_state_.UpdateDynamicState(amp;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(); }
-
(Рекомендуется) Вы можете попробовать использовать встроенную опцию python для обслуживания нескольких возвращаемых данных. Оставил вашу функцию C в ее начальной форме и вызывал на python таким образом:
VarA, VarB = Step(action)
Я предполагаю, что у вас есть ссылка на
Cassie2d::Step(ControllerTorque* action)
метод в вашем коде python, однако вы предоставили очень маленький фрагмент.
Комментарии:
1. lib = cdll. LoadLibrary(‘../../bin/libcassie2d.so’) c_double_p = ctypes. УКАЗАТЕЛЬ (ctypes.c_double) Эти две строки кода использовались для доступа к динамической библиотеке, которая также была скомпилирована из кода c , lib. Пошаговая инструкция. argtypes = [ctypes.c_void_p, ctypes. УКАЗАТЕЛЬ (ControllerTorque)] библиотека. StepTorque.restype = None предназначен для определения входного аргумента и возвращаемых типов с использованием ctypes, не могли бы вы, пожалуйста, сказать мне, что делать с restype пожалуйста, я действительно ценю вашу помощь!
2. Я не уверен, как работает ваш код. Итак, строка
lib.StepTorque.restype = ctypes.c_double
извлекает значение? Если да, то какая часть этого кода ссылается на переменную name od, в которой возвращаемое значение является хранилищем?