C++ 浮点数据到uint8_t和memcpy,返回null

C++ 浮点数据到uint8_t和memcpy,返回null,c++,c,floating-point,C++,C,Floating Point,我有一个浮点变量,它需要作为uint8\u t传递给函数 如何转换回浮动原始值 代码: 我试图从uint8_t数组中获取浮点原始值,需要分配给probe[channel] uint8_t channel = message->GetOutMessage()->GetData()->data[0]; unsigned char* value = &message->GetOutMessage()->GetData()->data[1]; memcpy(&

我有一个浮点变量,它需要作为uint8\u t传递给函数

如何转换回浮动原始值

代码:

我试图从uint8_t数组中获取浮点原始值,需要分配给probe[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的值


请帮助

您的代码中有未定义的行为。一个
float
通常是四个字节长,而
uint8\t
是一个单字节。因此,至少要用三个字节覆盖数组

然后,当您在
GetLoopOutMessage
中传递它时,您只传递实际数组(两个字节),因此浮点数字现在丢失了它的大部分数据

您可能想使用例如

uint8_t args[1 + sizeof(float)];

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

要解决此问题,您应该使
args
数组
静态
,使其全局化(确实不推荐),或者在堆上动态分配它:

uint8_t* args = new uint8_t[1 + sizeof(float)];
一旦您使用完此指针(即检索数据时),请不要忘记将其删除。

尝试如下操作:

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;
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;
然后像这样传递:

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;
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;
然后像这样读出数据:

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;
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;
请注意,我在这里使用的是
new
/
delete
,而不是本地堆栈存储,因为您似乎正在回调中使用数据,所以我猜您的数据在读取之前已经被覆盖(碰巧为零)


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

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;
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;
然后像这样传递:

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;
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;
然后像这样读出数据:

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;
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;

非常感谢,但尽管更改为args[5],该值仍然保持为0。我从未见过任何“DAC”硬件将浮点作为参数,直接或作为字节复制到数组中。args数组保持args[5]={0,0,0,64,65},当探针号为0,电压为12时。@user2746930在快速测试我自己之后,
float
number
12.0
似乎是字节序列
0 64 65
,因此数据是正确的。然而,这可能是另一个问题,实际上是另一种未定义行为的情况。请看我的最新答案。哦,等等…'DACVoltage'-GetLoopOutMessage()在该数组中到底需要什么??虚拟PTCLoopOutMessage*GetLoopOutMessage(PTCHardware*源、uint8\u t地址、uint8\u t命令、const char*commandString、const uint8\u t*数据、大小\u t数据长度、PTCMessageType messageType、PTCMessagePriority)=0;这可能是可行的,但如果它希望浮点数正好在uint8之后,那么填充将是一个问题,除非结构已打包。@RetiredInja:给出的示例显示了“管道”的两端,因此我怀疑是否真的需要打包。只要他们能够更改两侧。我想
GetLoopOutMessage
可能有点像一个黑匣子。@RetiredInja:是的,它看起来像是一个直接传递数据的黑匣子。仔细想想,
sizeof
属性表明它复制了数据,因此malloc/free可能是一个糟糕的计划。