【问题标题】:How to access the multiple return variables compiled in python如何访问在python中编译的多个返回变量
【发布时间】:2019-07-27 11:50:39
【问题描述】:

我是编程新手,我用元组方法在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,因为它适用于一个返回的变量,它可能不适用于两个返回的变量。

非常感谢您的帮助!

【问题讨论】:

  • 提供一些细节 - 你使用什么 python 库?分段错误表明您可以初始化 python,但不能初始化一些附加模块(也许是 numpy?)。多次返回通常可以像这样访问:VarA, VarB = function_name(arguments)
  • lib = cdll.LoadLibrary('../../bin/libcassie2d.so')。 c++文件编译成动态库libcassie2d.so,上面的代码是在python中加载库,我可以加载一个返回变量,而不是我在c++中定义的两个变量

标签: python c++ segmentation-fault stdtuple ctype


【解决方案1】:

使用return std::make_tuple(mj_data_-&gt;qacc,mj_data_-&gt;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) 方法,但是您提供的 sn-p 非常小。

【讨论】:

  • lib = cdll.LoadLibrary('../../bin/libcassie2d.so') c_double_p = ctypes.POINTER(ctypes.c_double) 这两行代码是用来访问动态库的已经从 c++ 代码编译,还有 lib.StepTorque.argtypes = [ctypes.c_void_p, ctypes.POINTER(ControllerTorque)] lib.StepTorque.restype = None 用于使用 ctypes 定义输入参数和返回类型,请请告诉我如何处理重新输入,非常感谢您的帮助!
  • 我不确定您的代码是如何工作的。那么lib.StepTorque.restype = ctypes.c_double 行提取值?如果是,这段代码的哪一部分引用了返回值为 storage 的名称 od 变量?
猜你喜欢
  • 2021-07-31
  • 2011-10-26
  • 2022-01-06
  • 1970-01-01
  • 2013-06-18
  • 2021-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多