我发布这个问题是因为我觉得我不理解有关 C/C++ 库的一些基本概念。
假设我们有一个名为 lib_c 的库,保存一些状态(例如静态全局变量)。假设还有另一个库 lib_b 使用 lib_c。
现在,我正在编写一个程序A,它同时需要lib_b和lib_c。有什么方法可以使 A 使用的 lib_c 与 lib_b 使用的 lib_c 不同(即获取静态全局变量的单独副本)?
为了更好地说明我的挫败感,请参阅以下代码示例。
这是“有状态库”,它只有 2 个静态全局变量:
c.h:
#ifndef C_H
#define C_H
void init_variables(int a, int b);
int get_a();
int get_b();
#endif
抄送:
#include "c.h"
static int a_ = 0, b_ = 0;
void init_variables(int a, int b) {
a_ = a;
b_ = b;
}
int get_a() { return a_; }
int get_b() { return b_; }
这是另一个使用有状态库的库:
b.h:
#ifndef B_H
#define B_H
void read_b();
#endif
b.c:
#include <stdio.h>
#include "b.h"
#include "c.h"
void read_b() {
printf("As seen from b.c: %d, %d\n", get_a(), get_b());
}
这是我的代码,使用两个库:
a.c:
#include <stdio.h>
#include "b.h"
#include "c.h"
void read_a() {
printf("As seen from a.c: %d, %d\n", get_a(), get_b());
}
int main() {
init_variables(1, 2);
read_a();
read_b();
return 0;
}
read_a() 和 read_b() 都读取静态全局变量 1 和 2 的相同内容!看来 lib_b 和我的代码没有获得这些静态全局变量的不同副本。
我尝试过使用普通 gcc 命令进行编译和使用 CMake 进行构建。看看我写的CMakeLists:
cmake_minimum_required(VERSION 3.22)
project(UnderstandStatefulLibs VERSION 1.0 LANGUAGES C)
# c.c -> lib_c
add_library(lib_c c.c)
# b.c + lib_c -> lib_b
add_library(lib_b b.c)
target_link_libraries(lib_b PRIVATE lib_c)
# a.c + lib_b + lib_c -> executable
add_executable(main a.c)
target_link_libraries(main PRIVATE lib_b lib_c)
欢迎有关此主题的任何澄清。我想知道是否有可能获得静态全局变量的单独副本,如果可以,如何获得。
非常感谢!
通常,需要在内部存储某些状态的库会被实现,以便有一个“open_library()”调用,该调用分配包含状态的数据结构或类的新副本,并返回一个不透明句柄(例如,指向结构)。
在对库的所有其他调用中,用户必须提供句柄作为函数的第一个参数。
还应该有一个“close_library(handle) 调用,用于释放在“open_library()”中分配的状态结构。
用户看不到状态结构的内部,只能通过调用库中的函数并传递句柄来操作状态结构中包含的数据。