gpt4 book ai didi

c - 如何在运行时找到全局变量的地址?

转载 作者:太空宇宙 更新时间:2023-11-04 05:39:51 25 4
gpt4 key购买 nike

我们知道结构变量和全局变量的地址是在运行时分配的。我必须将这些地址传递给一个函数。我只有存储在二维数组中的变量名称。怎么做到的?

例如:有一些文件具有全局变量和结构变量。我已经从 .map 文件中收集了一个数组中的所有变量名称,但我想准确地知道变量的地址。

最佳答案

您不能将变量的名称作为字符串并将其转换为地址,这称为内省(introspection),标准 C 没有该功能。

可以做的是提供您自己的映射,例如:

int glob_one, glob_two;

typedef struct {
char *name;
int *addr;
} tMap;

tMap map[] = {
{"glob_one", &glob_one },
{"glob_two", &glob_two },
};

int *findVar (char *key) {
for (int i = 0; i < sizeof(map) / sizeof(map[0]); i++) {
if (strcmp (map[i].name, key) == 0) {
return map[i].addr;
}
}
return NULL;
}
:
int *glob_to_use = findVar ("glob_two");
if (glob_to_use != NULL)
*glob_to_use = 42;

如果您使用的是 POSIX 系统,dlsym可以获得关于全局命名空间的信息:

int glob_one;
:
int *glob_to_use = dlsym (RTLD_DEFAULT, "glob_one");
if (glob_to_use != NULL)
*glob_to_use = 42;

例如下面的代码:

#include <stdio.h>
#include <dlfcn.h>
int glob_one;
int main (int argc, char *argv[]) {
int *glob_to_use;
printf ("Old value is %d\n", glob_one);
glob_to_use = dlsym (RTLD_DEFAULT, "glob_one");
if (glob_to_use != NULL)
*glob_to_use = 42;
else
puts (dlerror());
printf ("New value is %d\n", glob_one);
return 0;
}

在 Linux 下编译时:

gcc -rdynamic -o testprog testprog.c -ldl

将产生:

Old value is 0
New value is 42

如果您使用的是 Windows 而不是 POSIX 系统,则等效调用是 GetProcAddress()。以下是与上述程序等效的程序:

#include <Windows.h>
#include <iostream>
extern "C" {
__declspec(dllexport) int glob_one = 13;
}
int main (void) {
std::cout << "Old value is " << glob_one << '\n';

HMODULE hMod = GetModuleHandle (NULL);
int *pGlobal = (int*) GetProcAddress (hMod, "glob_one");
*pGlobal = 42;

std::cout << "New value is " << glob_one << '\n';

return 0;
}

注意 extern "C"dllexport 的使用,这两者在这里都是必需的。第一个停止名称修改,因此您可以使用真实名称进行符号查找。第二个导出变量,以便 GetProcAddress() 可以找到它。

与上面的 Linux 一样,输出显示您可以通过其文本名称访问全局:

pax> gpatest
Old value is 13
New value is 42

关于c - 如何在运行时找到全局变量的地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22086636/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com