c++ - 使对象只能由其库访问,而不能由程序中的任何其他例程访问
问题描述
假设我有两个(或更多)c 函数func1()
,并且func2()
都需要一个缓冲区变量int buff
。如果这两个函数都保存在单独的文件func1.c和func2.c中,我如何制作它以便buff
只能访问func1()
而func2()
不是调用例程(或任何其他例程)。
这是一个示例设置:
文件func1.c:
/*func1.c*/
static int buff;
int *func1(int x)
{
buff = x;
return &buff;
}
文件func2.c:
/*func2.c*/
static int buff;
int *func2(int x)
{
buff = x;
return &buff;
}
标头header.h:
/*header for func1.c and func2.c*/
//multiple inclusion guard not present.
int *func1(int);
int *func2(int);
文件main.c:
#include<stdio.h>
#include"header.h"
int main()
{
int *ptr;
ptr = func1(1);
printf("&buff = %p , buff = %d\n", ptr, *ptr);
ptr = func2(2);
printf("&buff = %p , buff = %d\n", ptr, *ptr);
return 0;
}
正如预期的那样,输出显示了 buff 的不同内存位置。
&buff = 0x55b8fd3f0034 , buff = 1
&buff = 0x55b8fd3f0038 , buff = 2
但我只需要一个副本buff,不需要更多。
当然,我可以将两个函数放在同一个文件中,并定义buff
为static int但是我将失去分别编译函数的能力。
如果我放入int buff
一个单独的buff.c并在func1.c和func2.c 中将其声明为extern,那么调用例程(在本例中为 main )将很容易访问它。
基本上,我需要创建一个在同一个外部对象上工作的函数库,只有它们可以访问。调用例程可能不需要所有函数,因此我不想将它们放在一个文件中并创建未使用的代码。但是对象必须只有一个副本。
如果可以的话,请帮助我如何做同样的事情。
解决方案
C 标准没有提供执行此操作的方法。它通常使用 C 标准之外的编译器和链接器的特性来完成。这是在 macOS 上使用 Apple 开发人员工具的示例。对于适合您环境的选项,您应该指定您正在使用的构建工具和版本,例如您使用的是 Apple 工具、GNU 工具、Microsoft 工具还是其他工具。
有了这个a.c
:
#include <stdio.h>
int x = 123;
void a(void)
{
printf("In a.c, x is %d.\n", x);
}
这在b.c
:
#include <stdio.h>
extern int x;
void b(void)
{
printf("In b.c, x is %d.\n", x);
}
我们将源文件编译为目标模块:
clang -c a.c b.c
然后将它们链接到新的目标模块,同时请求不导出r.o
符号x
(在链接器视图中):_x
ld -r -o r.o -unexported_symbol _x a.o b.o
然后,如果我们有另一个源文件c.c
尝试使用x
:
#include <stdio.h>
extern int x;
extern void a(void);
extern void b(void);
int main(void)
{
a();
b();
printf("In c.c, x is %d.\n", x);
}
尝试使用clang -o c c.c r.o
yield 构建可执行文件:
架构 x86_64 的未定义符号: “_x”,引用自: _main 在 c-139a35.o ld:未找到架构 x86_64 的符号
c.c
但是,如果我们删除引用的两行x
,则构建成功,程序将打印:
在 ac 中,x 是 123。 在公元前,x 是 123。
推荐阅读
- python - 如何使用 LIKE 子句转义 pymysql 中的 % 和 \ 符号?
- mysql - 使用模糊匹配将 2 个 MySQL 表合并为一个
- python - 修复我的代码以使用禁用按钮
- c# - Unity GameOver 屏幕
- java - 编译 Java/gradle discord bot
- java - 如何使用 map 计算列表中整数列表的总和并获得一个新列表,其中每个条目对应于每个计算的总和?
- javascript - 如何在没有框架的情况下使用 Javascript 发送电子邮件
- java - SonarQune 抱怨从 wsdl 文件生成的 _equalsCalc 变量不是瞬态的或可序列化的
- reactjs - 将 ref 传递给具有循环 ID 的函数?
- python - Tensorflow 对象检测 API 中的步骤是什么意思