6

以下代码驻留在一个设备中,当通过 IrDA 套接字连接枚举时,该设备将发出一个 deviceId (LXdeviceInfo)。这仅对解释为什么我想保持数据类型尽可能相似但能够使用 ansi C 进行编译很重要

使用 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: Innvalid 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.

}
4

2 回答 2

11

删除字符串文字周围的括号。括号使宏扩展为将衰减为指针类型的表达式,这使其无法在 C 编译器中编译。指针类型不能用于初始化数组。如果没有括号,则使用字符串文字来初始化数组。

#define PROD_FAMILY_NAME "product name goes here"

C 标准规定带括号的表达式与不带括号的表达式具有相同的类型,C.99 §6.5.1 ¶5:

带括号的表达式是主要表达式。它的类型和值与无括号表达式的相同。如果未加括号的表达式分别是左值、函数指示符或 void 表达式,则它是左值、函数指示符或 void 表达式。

但是,虽然字符串文字是一个表达式,但反之则不成立。具体来说,字符串文字本身不是类型,而是已定义的实体。数组的初始化允许字符串文字,C.99 §6.7.8 ¶14:

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

数组的其他允许初始化器在 C.99 §6.7.8 ¶16 中进行了描述:

否则,具有聚合或联合类型的对象的初始化程序应为元素或命名成员的初始化程序的大括号括起来的列表。

带括号的表达式不是字符串文字,也不是大括号括起来的初始值设定项列表。

于 2013-08-13T20:06:46.290 回答
0

作为PROD_FAMILY_NAME(常量)字符串,编译器期望ID被声明为uint8_t *ID;字符串通常表示为指向 C 中内存中字符的指针。请参见我的示例:http: //ideone.com/m5ZZl0

要像您一样使用字符数组执行此操作,您需要从产品系列名称到您的strcpy字节数组,因为据我所知,C 不支持直接数组分配。如果产品名称将是一个变量但不会更改并且不会超出范围,我建议使用-typed ,但如果您需要名称的副本并且不想动态分配您可能希望使用数组的内存(但请注意,旧版本的 C 标准不支持非静态长度数组,[尽管有一些方法可以在末尾使用可变长度数组来解决这个问题结构,但在这种情况下,您通常必须手动跟踪结构大小,因为此类数组将返回 0;诸如memcpyIDuint8_t*IDsizeof()strlen()应该仍然可以正常工作。)


似乎我忘记了,虽然不允许数组赋值,但char array[] = "literal string";仍然是这样的。(http://ideone.com/vilDOa vs. http://ideone.com/gEC2k2)所以我上面的内容有点毫无意义,但我确实认为如果你想要动态调整结构大小并不是一个好主意拥有这样一个结构的数组,在这种情况下,该char*方法可能是一个更好的主意(即使它只是指向其他地方的数组的指针)。

于 2013-08-13T20:07:55.720 回答