有没有一种方法可以修改这个C++结构体赋值块,使其直接在C语言中工作

ldioqlga  于 11个月前  发布在  其他
关注(0)|答案(2)|浏览(77)

下面的代码驻留在一个设备中,当通过IrDA套接字连接枚举时,该设备将发出一个deviceId(LXdeviceInfo)。
使用windows. h和af_irda. h的#includes,以下代码在C++编译器中编译时没有错误,但在C编译器中,(见这里的错误).理想情况下,我想初始化结构成员“ID”* 将其转换为字符数组,同时保持其类型与原始代码中的类型相同,这样我就可以测试LXdeviceInfo的值,就像它在从PC套接字连接对设备的调用中查询它。
有没有什么方法可以直接修改这个赋值块,使其在C语言中工作?

#include <windows.h>
#include <af_irda.h>

#define IR_HINT_COMPUTER  0x04
#define IR_HINT_EXT       0x80
#define IR_HINT_OBEX      0x20
#define IR_HINT_IRCOMM    0x04
#define IR_CHAR_ASCII       0
#define PROD_FAMILY_NAME ("product name goes here")

#define uint8_t unsigned char

const struct {
    uint8_t hint1;
    uint8_t hint2;
    uint8_t charset;
    uint8_t ID[sizeof(PROD_FAMILY_NAME)];
} devInfoStorage = 
{
    IR_HINT_COMPUTER | IR_HINT_EXT,   // hint1
    IR_HINT_OBEX | IR_HINT_IRCOMM,    // hint2
    IR_CHAR_ASCII,                    // charset
    PROD_FAMILY_NAME                  // Prod ID string
}; // ERROR here: Invalid initialization type: found 'pointer to char' expected 'unsigned char'

const uint8_t *LXdeviceInfo = (uint8_t *) &devInfoStorage;

/* The size of the device info */
const uint8_t LXdeviceInfoLen = sizeof(devInfoStorage);


void main(void)
{

    #define DEVICE_LIST_LEN    10

    unsigned char DevListBuff[sizeof (DEVICELIST) -
                              sizeof (IRDA_DEVICE_INFO) +
                              (sizeof (IRDA_DEVICE_INFO) * DEVICE_LIST_LEN)];

    int DevListLen = sizeof (DevListBuff);
    PDEVICELIST pDevList;

    pDevList = (PDEVICELIST) & DevListBuff;
         //code continues.
}

字符串

6pp0gazn

6pp0gazn1#

删除字符串字面量周围的圆括号。圆括号使宏扩展为一个表达式,该表达式将衰减为指针类型,这使得它不能在C编译器中编译。指针类型不能用于初始化数组。没有圆括号,字符串字面量用于初始化数组。

#define PROD_FAMILY_NAME "product name goes here"

字符串
C标准规定,带括号的表达式与无括号的表达式具有相同的类型,C.99 §6.5.1 ¶5:
带括号的表达式是主表达式。**它的类型和值与无括号的表达式相同。**如果无括号的表达式分别是左值、函数指示符或空表达式,则它是左值、函数指示符或空表达式。
然而,虽然字符串字面量是一个表达式,但匡威就不成立了。具体来说,字符串字面量本身不是一个类型,而是一个定义的实体。数组的初始化为字符串字面量提供了特定的允许,C.99 §6.7.8 <$14:

字符类型的数组可以由字符串字面量初始化,可选地用括号括起来。

其他允许的数组初始化式在C.99 §6.7.8中描述:
否则,具有聚合或联合类型的对象的初始化器应该是元素或命名成员的大括号括起的初始化器列表。
带括号的表达式不是字符串文字,也不是大括号括起的初始值设定项列表。

ryevplcw

ryevplcw2#

由于PROD_FAMILY_NAME是一个(常量)字符串,编译器期望ID被声明为类似uint8_t *ID;的东西,因为字符串通常表示为指向C中内存中字符的指针。
要使用字符数组来实现这一点,你需要从产品系列名称到ID字节数组执行strcpymemcpy,因为据我所知,C不支持直接数组赋值。如果产品名称将是一个变量,但不会改变,也不会超出范围,我建议使用uint8_t*类型的ID,但是如果你需要一个名字的副本,并且不想动态分配内存,你可能想坚持使用数组。(但请注意,旧版本的C标准也不支持非静态长度数组[尽管有一些方法可以通过在结构体的末尾添加可变长度数组来解决这个问题,但是在这种情况下,您通常必须手动跟踪结构体的大小,因为sizeof()将为此类数组返回0;不过,strlen()之类的东西应该仍然可以正常工作。)
似乎我忘记了,虽然数组赋值是不允许的,但像char array[] = "literal string";这样的东西仍然是允许的。(http://ideone.com/vilDOa vs. http://ideone.com/gEC2k2)所以我上面的内容有点无意义,但我确实认为,如果你想拥有一个这样的结构体数组,动态调整结构体大小并不是一个好主意,在这种情况下,char*方法可能是一个更好的主意(即使它只是指向其他地方的数组的指针)。

相关问题