C++ 浮点数据到uint8_t和memcpy,返回null
我有一个浮点变量,它需要作为uint8\u t传递给函数 如何转换回浮动原始值 代码: 我试图从uint8_t数组中获取浮点原始值,需要分配给probe[channel]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_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
number12.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可能是一个糟糕的计划。