Windows结构初始化错误C2099:初始化程序不是常量

问题描述 投票:1回答:1

我对Windows还是很陌生,我正在尝试在Windows上使用全局变量编译一个简单的DLL,并在Windows 10上使用Visual Studio 2017在我的测试应用程序中使用该全局变量。

这是应用程序的源代码

#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上编译似乎可行(唯一的区别是删除了__declspec)。 Windows为什么会引发编译错误?

c windows dll visual-studio-2017
1个回答
0
投票

使用__declspec(dllimport) const char globalArr[];,这意味着在运行的可执行文件链接到DLL之前,符号globalArr将不会获得值。即使使用导入库,此链接仍会在运行时发生。

“加载时动态链接”的过程与“运行时动态链接”类似,不同之处在于它发生在输入main之前。

因此,该值不能在静态数据初始化器中使用,因为C要求在编译时知道这些初始化器。

相反,您可以在链接DLL之后在main中设置值,例如:

MyStruct myArr[1];

int main()
{
    myArr[0].pData = globalArr;
}
© www.soinside.com 2019 - 2024. All rights reserved.