C - 将结构值中的变量名作为字符串访问

Posted

技术标签:

【中文标题】C - 将结构值中的变量名作为字符串访问【英文标题】:C - accessing variable names in struct values as strings 【发布时间】:2021-06-29 14:15:09 【问题描述】:

我有一个结构数组,其中 .act 值不是字符串,而是函数名:

cgi_object_t cgi_machine_learning_handlers[] =


    .path = "schema",
    .grp = ACC_GRP_ML,  
    .r_vdom = VDOM_PER_VDOM,
    .r_global = VDOM_PER_VDOM,
    .act = cgi_ml_schema,
    .flags = API_FLAG_NO_SCHEMA, 
,

    .path = "policy.svmattacktypes",
    .grp = ACC_GRP_ML,  
    .r_vdom = VDOM_PER_VDOM,
    .r_global = VDOM_PER_VDOM,
    .act = cgi_ml_policy_svmattacktypes_get,
    .flags = API_FLAG_NO_SCHEMA, 

我正在尝试以字符串的形式访问这些函数名—— cgi_ml_schema 等。有没有办法做到这一点?我尝试在下面使用#,但它抱怨程序中有杂散的'#'。

const char * var = json_object_object_get(request, #(m->act))
response = json_object_object_get(info, #(m->act));

【问题讨论】:

将名称添加为结构中的字段。 是的。有没有我不必这样做的替代方法?直接读取指针名称? @dbush 您可能必须创建一个X macro 才能在此处以可维护的方式添加某种内省。但是,只有在初始化函数指针后从不更改函数指针时,这才有效。 【参考方案1】:

您基本上是在询问是否可以从指针本身读取指针的名称。让我们试试吧。你能告诉我地址​​ 0x55c0c6e93190 的函数名称是什么吗?我觉得不是。任何人也不能,除非相应的名称存储在某个地方的内存中。编译后变量名称不再存在(除非您计划利用调试信息)。

但您可以尝试自动存储名称以及指针,如下所示:

#include <stdio.h>

typedef int (*fnptr_t)(int a, int b);

typedef struct named_ptr 
    fnptr_t ptr;
    const char *name;
 named_ptr;

named_ptr make_named_ptr(fnptr_t ptr, const char *name) 
    named_ptr p = ptr, name;
    return p;

#define MAKE_NAMED_PTR(x) make_named_ptr(x, #x)

typedef struct cgi_object_t 
    char *path;
    int grp, r_vdom, r_global;
    named_ptr act;
    int flags; 
 cgi_object_t;

enum dummy ACC_GRP_ML, VDOM_PER_VDOM, API_FLAG_NO_SCHEMA;
int cgi_ml_schema(int a, int b)  return 0; 
int cgi_ml_policy_svmattacktypes_get(int a, int b)  return 0; 

int main(void) 

    cgi_object_t cgi_machine_learning_handlers[] = 
        
            .path = "schema",
            .grp = ACC_GRP_ML,  
            .r_vdom = VDOM_PER_VDOM,
            .r_global = VDOM_PER_VDOM,
            .act = MAKE_NAMED_PTR(cgi_ml_schema),
            .flags = API_FLAG_NO_SCHEMA, 
        ,
        
            .path = "policy.svmattacktypes",
            .grp = ACC_GRP_ML,  
            .r_vdom = VDOM_PER_VDOM,
            .r_global = VDOM_PER_VDOM,
            .act = MAKE_NAMED_PTR(cgi_ml_policy_svmattacktypes_get),
            .flags = API_FLAG_NO_SCHEMA, 
        
    ;
    
    for (size_t i = 0; i < 2; ++i) 
        cgi_object_t *m = cgi_machine_learning_handlers + i;
        printf("%s is at address %p\n", m->act.name, m->act.ptr);
    
    
    return 0;

我真的猜到并编造了很多东西,但想法就在那里。下次,您应该提供Minimal, Reproducible Example。

测试它here。

如果您的编译器支持它们,则函数调用可以替换为复合文字。

【讨论】:

以上是关于C - 将结构值中的变量名作为字符串访问的主要内容,如果未能解决你的问题,请参考以下文章

数组名作函数参数时,实参与形参变量之间的数据传递是?

无法解析弹性 beantalk 中字符串值中的占位符

c语言里面的结构体是啥意思

数组名作为函数的参数属于啥传递为啥

如何在节点js中将变量名作为mongodb的集合名称传递

在结构中创建变量并访问同一结构中的变量