c - Windows 结构初始化错误 C2099 : initializer is not a constant

标签 c windows dll visual-studio-2017

我是 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 会抛出编译错误?

最佳答案

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

“加载时动态链接”在过程上与“运行时动态链接”类似,只是它发生在输入 main 之前。

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

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

MyStruct myArr[1];

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

关于c - Windows 结构初始化错误 C2099 : initializer is not a constant,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61515023/

相关文章:

python - 我怎样才能解决以下结果?

c# - 子项目引用的某些 DLL 未复制到解决方案的输出文件夹

c - 为什么模运算符不能在 C 中的 printf 函数中工作?

c - 将文本文件加载到二维数组中,然后与文字进行比较

c - 如何使用 libpng 将 C 代码中的 png 图像解码为原始字节?

windows - 如何查看服务启动时的日志文件?

c - Lex:查找输入的第一个排列

windows - D编程语言——无需按回车键输入

c# - 加载 DLL 的多个实例 (C#/.NET)

.net - 是否可以在 .net DLL 中嵌入和使用可移植的可执行文件?