【问题标题】:Converting from const void * to float array从 const void * 转换为浮点数组
【发布时间】:2012-04-30 16:56:55
【问题描述】:

我正在为 mbed 平台使用 rtos 库。我希望能够跳入线程,以恒定速率递增某个值,然后在线程结束时关闭线程。问题是从 mbed RTOS 库中实现 Thread 的方法只能采用 const void * 参数。 这没什么大不了的,除非我需要向它发送一个浮点值数组,其中一个值是指向我需要递增的值的指针(*joint),而其他值可以简单地是 const 那个控制增量的范围和速度。我以为我已经控制住了,并在这里找到了一些可以正确转换的简洁代码,但我仍然不断提出 0 值://float (*vals)[4] = (float (*)[4])args;

这里是代码,只剩下参与线程工作的两个函数。

void increment( void const *args ) { //float *joint, float inc, float target, int speed ) 
    //float (*vals)[4] = (float (*)[4])args;
    float *vals = (float* )args;

    // joint is the outside value I want to increment
    float *joint  = &vals[0];
    float inc    = vals[1];
    float target = vals[2];
    int   speed  = (int)vals[3];
    float start = 0.5;


    if( inc < 0 ) 
        for( *joint = start; *joint > target; *joint+=inc ) {
             wait( 0.1 / speed );
        }
    }


void thread_inc( float *joint, float inc, float target, int speed ){
    float args[4] = { *joint, inc, target, (float)speed };
    //Thread move( increment, args );
    Thread move( increment, &args );
    return;
}

提前感谢您为我指明正确方向的任何事情!

【问题讨论】:

    标签: c++ pointers casting rtos


    【解决方案1】:

    我绝对是从 jlunavtgrad、Pat 和 Burton Samograd 那里偷来的。我觉得他们的三个答案都真正回答了 OP。

    1. 使用表示要传递给新线程上下文的参数的结构可以更好地管理。

    2. args 数组位于堆栈上,并以thread_inc 的范围为界。通过用结构替换它,您仍然无法解决此处涉及的范围问题。因此,需要以其他线程上下文可以正确使用它们的方式分配参数(以任何形式)——这可以通过全局或堆上来完成。

    3. thread_incfloat *joint 参数被取消引用,该值用于填充参数。这似乎不是所需的行为,因为只会修改参数数组中复制的值。

    代码中的建议修改:

    struct thread_args {
      float * joint;
      float inc;
      float target;
      int speed;
    };
    
    
    void increment( void const *args ) {
      thread_args* threadArgs = static_cast<thread_args*>( args );
    
      float *joint  = threadArgs->joint;
      float inc    = threadArgs->inc;
      float target = threadArgs->target;
      int   speed  = threadArgs->speed;
      float start = 0.5;
    
      if( inc < 0 ){ 
        for( *joint = start; *joint > target; *joint+=inc ) {
           wait( 0.1 / speed );
        }
      }
    
      delete threadArgs;
    }
    
    void thread_inc( float *joint, float inc, float target, int speed ){
      thread_args* threadArgs = new thread_args;
      threadArgs->joint = joint;
      threadArgs->inc = inc;
      threadArgs->target = target;
      threadArgs->speed = speed;
    
      //Thread move( increment, args );
      Thread move( increment, threadArgs );
      return;
    }
    

    与此解决方案相关的最后一个建议是,不要以原始形式使用newdelete,而是使用某种智能指针,例如shared_ptr

    【讨论】:

      【解决方案2】:

      我建议不要尝试通过 void* 传递 args 列表,而是为您的 Thread args 定义一个结构,其中每个 arg 都有一个字段。填写它,然后将结构的地址作为 void* 传递。

      【讨论】:

        【解决方案3】:

        在风格上,我建议使用结构将此信息传递给您的线程。这将使您的代码更具可读性并在一定程度上清理语法。

        struct thread_args {
           float * joint;
           float inc;
           float target;
           int speed;
        };
        

        【讨论】:

        • 虽然我同意这种 style 会更受欢迎,但它并不能真正回答问题。
        【解决方案4】:

        您正在堆栈上创建 args 数组,因此当您创建线程时,函数返回时它超出了范围。您应该使用 new/malloc 分配 args 数组,对其进行初始化,然后将其传递给移动线程。移动线程完成后,您可以释放数组。另一种选择是在调用函数中创建传递给 thread_inc 的数组。

        【讨论】:

        • 似乎有两个同样重要的修复方法,包括这个答案和帕特的。
        【解决方案5】:

        您在将 *joint 传递给 increment 函数时取消了对它的引用,因此该函数永远无法更新该值。

        试试这个:

        void increment( void const *args ) { //float *joint, float inc, float target, int speed ) 
            //float (*vals)[4] = (float (*)[4])args;
            float *vals = (float* )args;
        
            // joint is the outside value I want to increment
            float *joint  = (float *)vals[0];
            float inc    = vals[1];
            float target = vals[2];
            int   speed  = (int)vals[3];
            float start = 0.5;
        
        
            if( inc < 0 ) 
                for( *joint = start; *joint > target; *joint+=inc ) {
                     wait( 0.1 / speed );
                }
            }
        
        
        void thread_inc( float *joint, float inc, float target, int speed ){
            float args[4] = { (float)joint, inc, target, (float)speed };
            //Thread move( increment, args );
            Thread move( increment, &args );
            return;
        }
        

        【讨论】:

        • 希望他不是 64 位系统。浮点数是 32 位。正如下面所建议的那样,结构会是一个更好的主意。
        猜你喜欢
        • 1970-01-01
        • 2020-06-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多