C程序得到的变量名称作为输入和打印值 [英] C program to get variable name as input and print value

查看:128
本文介绍了C程序得到的变量名称作为输入和打印值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个程序test.c的

I have a program test.c

int global_var=10;
printf("Done");

我做

gcc -g test.c -o test

我的查询
有没有一种方法,我可以得到变量名作为参数(说global_var),并打印的价值。

My query is Is there a way i can get the variable name as argument (say "global_var") and print the value.

感谢

推荐答案

在一般情况下,这是不可能通过名称在运行时全局变量来访问。有时,这可能取决于操作系统,编译器是如何调用。我还是认为要解引用一个全局变量,你知道它的类型。

In general, it is not possible to access at runtime global variables by name. Sometimes, it might depend upon the operating system, and how the compiler is invoked. I still assume you want to dereference a global variable, and you know its type.

然后在Linux和其他一些系统,您可以使用的dlopen(3 )用 NULL 路径(以获取可执行的手柄),然后使用则dlsym 的全局变量名来获得它的地址;那么你可以施放该无效* 指针到相应类型的指针,并取消对它的引用。请注意,你需要知道的类型(或至少有C在其名称中的变量类型公约EN $ C $,C ++是做与的名称重整)。如果您编译和调试信息的链接(即的gcc -g )类型的信息在其的 DWARF 路段的 ELF可执行,所以有一些方法得到它。

Then on Linux and some other systems, you could use dlopen(3) with a NULL path (to get a handle for the executable), then use dlsym on the global variable name to get its address; you can then cast that void* pointer to a pointer of the appropriate type and dereference it. Notice that you need to know the type (or at least have a convention to encode the type of the variable in its name; C++ is doing that with name mangling). If you compiled and linked with debug information (i.e. with gcc -g) the type information is in its DWARF sections of your ELF executable, so there is some way to get it.

这工作,如果您使用链接可执行 -rdynamic -ldl

This works if you link your executable using -rdynamic and with -ldl

另一种可能性是自定义您最近 GCC 用自己的 MELT 扩展,它会记住并在稍后重新使用一些编译器内部重新presentations的(即的 GCC的的-s 涉及全局变量)。使用MELT register_finish_decl_first 函数注册在声明的处理程序。但是,这将需要一些工作(编码您的MELT扩展名)。

Another possibility might be to customize your recent GCC with your own MELT extension which would remember and later re-use some of the compiler internal representations (i.e. the GCC Tree-s related to global variables). Use MELT register_finish_decl_first function to register a handler on declarations. But this will require some work (in coding your MELT extension).

您可以用(便携式)preprocessor技巧来实现自己的目标(在运行时通过名字来访问变量)。

You could use (portable) preprocessor tricks to achieve your goals (accessing variable by name at runtime).

最简单的方法可能会定义,并按照自己的惯例。例如,你可以有一个包含就像

The simplest way might be to define and follow your own conventions. For example you could have your own globvar.def header file containing just lines like

 /* file globvar.def */
 MY_GLOBAL_VARIABLE(globalint,int)
 MY_GLOBAL_VARIABLE(globalint2,int)
 MY_GLOBAL_VARIABLE(globalstr,char*)
 #undef MY_GLOBAL_VARIABLE

和你采用的惯例,所有的全局变量在上述 globvar.def 文件。那么你会的#includeglobvar.def几次的。例如,在全局头,展开 MY_GLOBAL_VARIABLE 一些的extern 声明:

And you adopt the convention that all global variables are in the above globvar.def file. Then you would #include "globvar.def" several times. For instance, in your global header, expand MY_GLOBAL_VARIABLE to some extern declaration:

 /* in yourheader.h */
 #define MY_GLOBAL_VARIABLE(Nam,Typ) extern Typ Nam;
 #include "globvar.def"

在你的的main.c 你需要一个类似的伎俩来的声明的全局的

In your main.c you'll need a similar trick to declare your globals.

在其他地方你可能定义一个函数的名字来获得整型变量:

Elsewhere you might define a function to get integer variables by name:

 /* return the address of  global int variable or else NULL */
 int* global_int_var_by_name (const char*name) {
    #define MY_GLOBAL_VARIABLE(Nam,Typ) \
      if (!strcmp(#Typ,"int") && !strcmp(name,#Nam)) return (int*)&Nam;
    #include "globvar.def"
      return NULL;
 }

等等...我使用字符串化的宏参数

这样的preprocessor技巧纯粹是标准的C,并会与任何兼容的C99编译器的工作。

Such preprocessor tricks are purely standard C and would work with any C99 compliant compiler.

这篇关于C程序得到的变量名称作为输入和打印值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆