【问题标题】:extern keyword behavior with Visual Studio使用 Visual Studio 的 extern 关键字行为
【发布时间】:2014-04-10 03:21:33
【问题描述】:

我创建了这个最小示例来说明我在 Visual Studio 2008 中的 extern 声明问题(编译 python 2.7 扩展所必需的)。同样的例子也适用于 gcc。 结果是我有 2 个单独的 global_var 变量,而不是 lib.c 中的唯一变量

库接口:lib.h

#ifndef LIB_H
#define LIB_H 1

int __declspec( dllexport ) displayGlob();

#endif // LIB_H

库代码

// lib.c
#include<stdio.h>

int global_var=2;

int __declspec( dllexport ) displayGlob() {
    printf("lib.c global_var=%d\n", global_var);
    return global_var;
}

使用库变量“global_var”和函数displayGlob()的用户代码

// main.c

#include"lib.h" 
#include<stdio.h>
#include<stdlib.h>

extern int global_var=0; // must be initialized otherwise "error LNK2001: unresolved external symbol global_var"

int main(int argc, char *argv[]) 
{
  printf("main.c global_var=%d\n", global_var);
  displayGlob();
  global_var = 3;
  printf("main.c global_var=%d\n", global_var);
  displayGlob();
  exit(0);
}

执行结果为:

main.c global_var=0
lib.c global_var=2
main.c global_var=3
lib.c global_var=2

问题:

1 - 为什么我必须用 Visual Studio 而不是 Gcc 来初始化 lib.h 中的 extern 变量?

2 - 为什么第二个 displayGlob() 显示的 global_var lib.c 没有修改为 3 ?

感谢任何提示!

劳伦特

更新:将 global_var 的 extern 声明从 lib.h 移至 main.c(甚至更简单的示例) 当然问题仍然存在......

【问题讨论】:

  • 是的,你有两个全局变量。一个在 DLL 中,另一个在 EXE 中。不要那样做。
  • 在 .c 文件中,标记变量 extern 或包含标题。此外,您几乎不想在标头中定义变量(因此删除初始化)。
  • 标头(和 global_var 的外部声明)已包含在 main.c 中。如果我不初始化extern,我有一个LINK错误

标签: c visual-studio variables extern


【解决方案1】:

因为 C 预处理器在调用 #include 时基本上会粘贴内容,因此与在 main.c 文件中声明 extern 相同。这意味着这个符号被定义了两次(在main.clib.c 中)。

您应该做的是将extern 声明添加到lib.c(例如通过包含lib.h)并在那里初始化值,然后从lib.h 中删除初始化。

所以应该是这样的:

lib.h:

extern global_var;

lib.c:

#include "lib.h"
int global_var=2;

main.c

#include "lib.h"
(no global_var definition/declaration here)

【讨论】:

  • .c 文件中的 extern 不是一个好主意。 Extern 不是一个定义,它只是一个声明。因此,它可以在一个文件中多次使用。
  • 你说得对,extern不能和定义一起使用,只能和声明一起使用。
  • 在 lib.c 中添加 lib.h 时(我在询问之前已经尝试过)我有一个重新定义错误:1>.\lib.c(7) : error C2374: 'global_var' : redefinition;多重初始化 1> vs2008\main\lib.h(4) : 参见 'global_var' 的声明
  • @Iclevy:你做错了什么。正如您的错误消息所述,global_var 有两个定义,而lib.c 中应该只有一个定义。然后,您应该有多个 global_var 声明和 extern 关键字 - 在每个使用此变量的文件中都有一个声明。请参阅我的更新答案。
  • 应用您的建议:使用“extern int global_var;”通过 lib.h 包含在 main.c 中,我有“main.obj:错误 LNK2001:未解析的外部符号 global_var”
【解决方案2】:

解决了我自己,我的错。

在 Gcc 下,我构建了一个静态库和一个动态库。我的 main.c 与 STATIC 库链接,因此在链接时解决了 lib.c 和 main.c 之间的变量解析。我忘记了。

在Visual Studio下,我只建了一个DYNAMIC库,所以DLL和main.o之间不能发生正常的变量链接

对造成的任何混乱感到抱歉...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多