将数据浮动到uint8_t和memcpy,返回null

时间:2013-09-04 12:55:36

标签: c++ c floating-point

我有一个float变量,需要作为uint8_t传递给函数。

如何转换回浮动原始值。

代码:

bool SetAnalog(uint8_t number, float voltage, MessagePriority priority, Callback clbck)
{
    uint8_t args[2];
    args[0] = number;
    memcpy(&(args[1]),&voltage,sizeof(float));

    PTCLoopOutMessage* message = parent()->GetLoopOutMessage(this,
                                                             this->address(),
                                                             _OutputVoltage,
                                                             "DACVoltage",
                                                             args,
                                                             sizeof(args),
                                                             Device,
                                                             priority);
    message->SetCallback(clbck);

    return ProcessOutMessage(message);
}

我尝试从uint8_t数组中取回浮点原始值并需要分配到探测[channel]

uint8_t channel = message->GetOutMessage()->GetData()->data[0];
unsigned char* value = &message->GetOutMessage()->GetData()->data[1];
memcpy(&__output.output.probe[channel].dac, value, sizeof(float));

我总是得到0的值,

请帮助

2 个答案:

答案 0 :(得分:7)

您的代码中存在未定义的行为。 float通常为四个字节长,而uint8_t是单个字节。所以你用至少三个字节覆盖你的数组。

然后当您在GetLoopOutMessage中传递它时,您只传递实际数组(这是两个字节),因此浮点数现在缺少其大部分数据。

您可能想要使用例如。

uint8_t args[1 + sizeof(float)];

如果GetLoopOutMessage没有复制传递给它的数据,那么你有另一种未定义行为的情况,即传递一个指向局部变量的指针。当SetAnalog函数返回时,存储局部变量的内存空间将被下一个函数调用重用。这意味着args数组不再存在于内存中,而以前它可能存在其他数据。

要解决此问题,您应该创建args数组static,使其成为全局(真的不推荐)或者在堆上动态分配它:

uint8_t* args = new uint8_t[1 + sizeof(float)];

完成后,请不要忘记delete此指针(即检索数据时)。

答案 1 :(得分:0)

试试这样:

struct MyArgs {
  uint8_t channel;
  float voltage;
} *args = new MyArgs();
args->channel = number;
args->voltage = voltage;

然后像这样传递:

....GetLoopOutMessage(....., (uint8_t *)args, sizeof(*args), ....)

并按如下方式读取数据:

struct MyArgs {
  uint8_t channel;
  float voltage;
} *args = (struct MyArgs *)message->GetOutMessage()->GetData()->data;

uint8_t channel = args->channel;
__output.output.probe[channel].dac = args->voltage;

delete args;

请注意,我在这里使用了new / delete,而不是本地堆栈存储,因为您似乎在回调中使用数据,因此我猜测您的数据已被覆盖(在你开始阅读它之前,为零。


如果new / delete不合适(GetLoopOutMessage复制数据),请按以下方式执行操作:

struct {
  uint8_t channel;
  float voltage;
} args = {number, voltage};

然后像这样传递:

....GetLoopOutMessage(....., (uint8_t *)&args, sizeof(args), ....)

并按如下方式读取数据:

struct mydata {
  uint8_t channel;
  float voltage;
} *args = (struct mydata *)message->GetOutMessage()->GetData()->data;

uint8_t channel = args->channel;
__output.output.probe[channel].dac = args->voltage;