Различия между struct в C и С++

Я пытаюсь преобразовать структуру С++ в C, но продолжать получать "необъявленный идентификатор"? Имеет ли С++ другой синтаксис для ссылки на структуры?

struct KEY_STATE 
{
    bool kSHIFT; //if the shift key is pressed 
    bool kCAPSLOCK; //if the caps lock key is pressed down
    bool kCTRL; //if the control key is pressed down
    bool kALT; //if the alt key is pressed down
};

Я использую переменную типа KEY_STATE внутри другой структуры:

typedef struct _DEVICE_EXTENSION
{
    WDFDEVICE WdfDevice;
    KEY_STATE kState;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

приводит к ошибке C2061: синтаксическая ошибка: идентификатор 'KEY_STATE'

... в строке KEY_STATE kState; Я создаю компилятор WDK, если это имеет значение. Конечно, это файл заголовка. Я портирую драйвер С++ WDM на WDF и C.

Это статья MSDN для C2061.

Инициализатор может быть заключен в круглые скобки. Чтобы избежать этой проблемы, вставьте объявление в круглые скобки или сделайте его typedef.

Эта ошибка также может быть вызвана, когда компилятор обнаруживает выражение как аргумент шаблона класса; используйте typename, чтобы сообщить компилятору, что это тип.

Изменение KEY_STATE в typedef struct по-прежнему вызывает эту ошибку и фактически вызывает намного больше. В скобках нет свободных скобок или вещей, это то, что предлагает статья.

Ответы

Ответ 1

В C имя типа struct KEY_STATE.

Итак, вы должны объявить вторую структуру как

typedef struct _DEVICE_EXTENSION
{
    WDFDEVICE WdfDevice;
    struct KEY_STATE kState;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

Если вы не хотите писать struct все время, вы можете использовать typedef declare KEY_STATE, аналогичный DEVICE_EXTENSION:

typedef struct _KEY_STATE
{
    /* ... */
} KEY_STATE;

Ответ 2

В C до C99 нет типа bool.

Кроме того, нет типа KEY_STATE, когда вы делаете struct KEY_STATE.

Попробуйте это вместо:

typedef struct _KEY_STATE 
{
    unsigned kSHIFT : 1; //if the shift key is pressed 
    unsigned kCAPSLOCK : 1; //if the caps lock key is pressed down
    unsigned kCTRL : 1; //if the control key is pressed down
    unsigned kALT : 1; //if the alt key is pressed down
} KEY_STATE;

Ответ 3

Вам нужно обратиться к KEY_STATE с помощью struct KEY_STATE. В С++ вы можете оставить struct вне, но не в обычном C.

Другим решением является создание псевдонима типа:

typedef struct KEY_STATE KEY_STATE

Теперь KEY_STATE означает то же самое, что struct KEY_STATE

Ответ 4

Вы могли/должны были наследовать структуру, чтобы вам не понадобилось ключевое слово struct при каждом объявлении переменной этого типа.

typedef struct _KEY_STATE 
{
    bool kSHIFT; //if the shift key is pressed 
    bool kCAPSLOCK; //if the caps lock key is pressed down
    bool kCTRL; //if the control key is pressed down
    bool kALT; //if the alt key is pressed down
} KEY_STATE;

Теперь вы можете сделать:

KEY_STATE kState;

или (как в примере, который у вас есть):

struct KEY_STATE kState;

Ответ 5

Вы должны квалифицировать переменную struct с ключевым словом struct:

typedef struct _DEVICE_EXTENSION
{
    WDFDEVICE WdfDevice;
    struct KEY_STATE kState;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

Когда вы используете DEVICE_EXTENSION, вам не нужно использовать 'struct', потому что вы выполняете определение структуры и typedef в одном составном заявлении. Таким образом, вы можете сделать то же самое для KEY_STATE, если хотите использовать его в подобном fasion:

typedef struct _KEY_STATE_t
{
    bool kSHIFT; //if the shift key is pressed 
    bool kCAPSLOCK; //if the caps lock key is pressed down
    bool kCTRL; //if the control key is pressed down
    bool kALT; //if the alt key is pressed down
} KEY_STATE;