首页 > 解决方案 > 通过引用而不是指向缓冲区的指针传递结构的转换问题

问题描述

struct通过引用传递时出现转换错误。将指针传递给缓冲区可以正常工作。该功能getstuff()实际上是libusb_claim_interface()删除了不相关的部分。我正在尝试从插入 Linux 机器的 USB 设备中取回一大块数据。

数据是这样进来的struct

typedef struct mystruct {
  unsigned char a;
  unsigned short b;
  unsigned char c;
  unsigned char d;
  ... /* 40 more members of unsigned char */
} mystruct_t;

但是,我使用的代码传递了一个无符号字符的缓冲区。然后缓冲区需要设置每个单独的结构成员。

例如:

getstuff(unsigned char *data, int length);
void foo(void)
{
  unsigned char apple;
  unsigned short banana;
  unsigned char cherry;
  unsigned char date;
  ...
  unsigned char buffer[44];

  sendstuff(...);
  getstuff(buffer, 44);
  apple = buffer[0];
  banana = buffer[1];
  cherry = buffer[2];
  date = buffer[3];
  ...
}

而不是这样做,我想实际定义一个struct(上面)并传递对它的引用,然后明智地访问成员,如下所示:

getstuff(unsigned char *data, int length);
void foo(void)
{
  unsigned char apple;
  unsigned short banana;
  unsigned char cherry;
  unsigned char date;
  ...
  mystruct_t *fruits;

  sendstuff(...);
  getstuff((unsigned char) fruits, sizeof(mystruct_t));
  apple = fruits->a;
  banana = fruits->b;
  cherry = fruits->c;
  date = fruits->d;
  ...
}

但这不起作用。首先我在编译时得到这个:

warning: cast from pointer to integer of different size [-Wpointer
-to-int-cast]
(unsigned char) fruits,

warning: passing argument 3 of ‘getstuff’ makes pointer from
integer without a cast [-Wint-conversion]

libusb.h然后,这个(在解析时被抛出):

note: expected ‘unsigned char *’ but argument is of type ‘unsigned char’
int LIBUSB_CALL libusb_bulk_transfer(libusb_device_handle *dev_handle,

当我运行程序时,设备似乎发回了 21906 字节,而不是预期的 44 字节。如果我将 fruits 转换为 ( unsigned char *),程序编译没有任何问题,但随后我会返回 21900 到 22060 字节之间的任何地方。我可以通过像在原始代码中一样简单地传递一个无符号字符数组来“解决”这个问题,然后这样做将指针复制到mystruct_t *fruits

fruits = (mystruct_t *) buffer;

但我真的很想知道发生了什么以及为什么我在转换结构时遇到这么多麻烦。

标签: clinuxcastinglibusblibusb-1.0

解决方案


getstuff((unsigned char) fruits, sizeof(mystruct_t));=>getstuff((unsigned char *) fruits, sizeof(*fruits));

fruits = (mystruct_t *) buffer;这个被称为“指针双关语”,不安全,不便携,一般是 UB

另一个问题是您没有为 fruits 结构分配内存。

您可以:

  mystruct_t fruits;
  ....
  getstuff((unsigned char *)&fruits, sizeof(fruits));

或者

  mystruct_t *fruits = malloc(sizeof(*fruits));
  /* malloc checks + .... */
  getstuff((unsigned char *)fruits, sizeof(*fruits));

推荐阅读