Windows ошибка инициализации структуры C2099: инициализатор не является константой - PullRequest
3 голосов
/ 30 апреля 2020

Я довольно новичок в Windows и пытаюсь скомпилировать простую DLL на Windows с глобальной переменной и использовать глобальную переменную в моем тестовом приложении, используя Visual-Studio 2017 на Windows 10.

Вот исходный код для приложения

#include <stdio.h>

__declspec(dllimport) const char globalArr[];

typedef struct {
    const char *pData;
} MyStruct;

MyStruct myArr[] = {
    {
        globalArr
    }
};

int main() {
    printf("1 = %d\n", myArr[0].pData[0]);
    printf("2 = %d\n", myArr[0].pData[1]);
    printf("3 = %d\n", myArr[0].pData[2]);

    printf("1 = %d\n", globalArr[0]);
    printf("2 = %d\n", globalArr[1]);
    printf("3 = %d\n", globalArr[2]);

    return 0;
}

Вот исходный код для DLL

__declspec(dllexport) const char globalArr[] = {
    0x00, 0x01, 0x02
};

Когда я компилирую основное приложение, используя следующий CMake проект

cmake_minimum_required(VERSION 3.9)

project(temp C)

add_library(mylib SHARED lib.c)
add_executable(myexec main.c)

target_link_libraries(myexec mylib)

Я получаю следующую ошибку «main. c (11): ошибка C2099: инициализатор не является константой». Компиляция на linux, кажется, работает (единственное отличие - удаление __declspe c). Почему Windows выдает ошибку компиляции?

1 Ответ

4 голосов
/ 30 апреля 2020

С __declspec(dllimport) const char globalArr[]; это означает, что символ globalArr не получит значение, пока запущенный исполняемый файл не будет связан с DLL. Даже при использовании библиотеки импорта это связывание происходит во время выполнения.

«Динамическое связывание во время загрузки c связывание» аналогично процедуре «Динамическое связывание во время выполнения c связывание», за исключением того, что оно происходит до ввода main.

Следовательно, значение нельзя использовать в инициализаторе данных stati c, поскольку C требует, чтобы эти инициализаторы были известны во время компиляции.

Вместо этого вы можете установить значение в main после того, как DLL будет связана Например:

MyStruct myArr[1];

int main()
{
    myArr[0].pData = globalArr;
}
...