Reputation: 401
I have an array of structs, where the .act values are not strings, but function names:
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,
}
I'm trying to access these function names -- cgi_ml_schema and such, as strings. Is there a way to do this? I tried using # below but it's complaining that there are stray '#'s in the program.
const char * var = json_object_object_get(request, #(m->act))
response = json_object_object_get(info, #(m->act));
Upvotes: 0
Views: 534
Reputation: 3418
You are basically asking if you can read the name of a pointer from the pointer itself. Lets try it. Can you tell me what is the name of the function at address 0x55c0c6e93190? I guess no. Nor can anyone, unless the corresponding name is stored in memory somewhere. After compilation the name of variables is no more (unless you plan of leveraging Debug information).
But you can try to automate the storing of the name along with the pointer like this:
#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;
}
I really guessed and made up a lot of stuff, but the idea is there. Next time, you should provide a Minimal, Reproducible Example.
Test it here.
If your compiler supports them, the function call can be replaced by compound literals.
Upvotes: 1