【问题标题】:Accessing global variable in static library访问静态库中的全局变量
【发布时间】:2022-11-07 04:18:33
【问题描述】:

我有一个自定义 LLVM 编译器,它将全局变量 (glob_var) 放入数据部分。当我执行以下主程序程序:

#include <stdio.h>
extern unsigned char glob_var[];

int main() {
    printf("%x\n", glob_var[0]);
    return 0;
}

打印内容。现在我正在尝试编写一个静态库库文件访问此变量:

#include <stdio.h>
extern unsigned char glob_var[];

static void __attribute__((constructor)) ctor() {

    printf("%x\n", glob_var[0]);
}

我正在编译:

clang -c -Wall -o lib.o lib.c
llvm-ar rc lib.a lib.o
clang -c -o main.o main.c
clang -o main.out -Wl,--whole-archive lib.a -Wl,--no-whole-archive main.o

我得到:

ld.lld: error: undefined symbol: glob_var 
>>> referenced by lib.c
>>>               lib.o:(ctor) in archive lib.a

最后一个命令。

请注意,glob_var 变量是在 main.c 编译期间创建的。当我反汇编 main.o 时,glob_var 在数据部分:

Disassembly of section .data:
0000000000000000 <glob_var>:

【问题讨论】:

  • clang -c -fPIE -Wall -o lib.o lib.c 创建一个 object file,而不是 shared library
  • 也许clang做了一些技巧,但如果glob_var在所有文件中都声明为extern,那么这些文件中的任何一个都不应该定义它......我建议删除lib.c中的“extern”字样。
  • 谁能知道您的自定义编译器是如何破坏事物的?发布一个每个人都可以复制的例子。

标签: c


【解决方案1】:

实际上变量glob_var 没有在模块中定义。您可以对“main.o”进行相同的诊断。 (当我试图重现你的问题时,我得到了“main.o”的错误。)

请决定哪个模块应该定义变量,这意味着为其提供实际空间。在您的示例中,删除“main.c”或“lib.c”中的extern

关于你的反汇编:由于对象模块“main.o”没有链接,它只是表明它知道一个变量glob_var。但它没有分配。


总之,正确的TM值声明和定义全局变量的方法是使用一个头文件,它“传输”关于它们的知识。所有需要知道这些全局变量的来源都包括头文件。最后一个源文件定义了全局变量,它也包含头文件。这样,您就可以让编译器检查声明和定义是否匹配。

在您的情况下,此文件声明了变量。预处理器条件构造称为“header guard”,不知道的请自行研究用法。

/* lib.h */

#ifndef LIB_H
#define LIB_H

extern unsigned char glob_var[];

#endif

主要来源将包括头文件。

/* main.c */

#include <stdio.h>

#include "lib.h"

int main() {
    printf("%x
", glob_var[0]);
    return 0;
}

我决定让库定义变量,因为变量似乎属于库。此外,我在其定义中设置了变量的大小。

/* lib.c */

#include <stdio.h>

#include "lib.h"

#define GLOB_VAR_SIZE 10

unsigned char glob_var[GLOB_VAR_SIZE];

static void __attribute__((constructor)) ctor() {

    printf("%x
", glob_var[0]);
}

【讨论】:

  • 更好的解决方案是使用带有外部声明的头文件
  • @0_______ 像这样?
猜你喜欢
  • 2012-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-28
相关资源
最近更新 更多