在具有动态库的结构中获取成员的地址

时间:2019-01-02 23:48:45

标签: c

通过查看以下答案:https://stackoverflow.com/a/4671482/1770034我可以使用dlsym在C中获取全局变量。是否可以从结构中获取成员。

我猜如果我在共享库中有以下代码:

header.h

struct myStruct
{
    int a;
    int b;
};

imp.c

struct myStruct structure = { 123, 456 };

我可以包含相同的header.h文件,并将整个指针转换为结构myStruct *。 struct myStruct * capturedStructure = (struct myStruct*) dlsym(handle, "structure");

但是,有没有一种方法可以直接将地址发送给成员。我猜我无法执行以下操作:int* c = (int*) dlsym(handle, "structure.b");

由于dlsym允许一个人单独获取函数或全局变量(没有标题),因此我希望我也可以在不需要标题的情况下获取成员。

2 个答案:

答案 0 :(得分:2)

  

直接向会员发送的地址

正常方式如下:

struct myStruct *pnt = (struct myStruct*) dlsym(handle, "structure");
int *b = &pnt->b;

现在让我们替换s/pnt/((struct myStruct*) dlsym(handle, "structure"))/。那是:

int *b = &((struct myStruct*) dlsym(handle, "structure"))->b;
  

是否没有定义结构的编译器? (来自评论)

这可能有点棘手,但是我们可以做到。您将需要导出另一个符号:

const size_t offsetof_member_b_in_myStruct = offset(struct myStruct, b);

然后再在客户端代码中:

int *b = (int*)(
             (uintptr_t)dlsym(handle, "structure") + 
             *(size_t*)dlsym(handle, "offsetof_member_b_in_myStruct")
         );

我猜这样的API可能是一致的,但感觉很糟糕。将结构导出到客户端代码更简单。也许在一般情况下,最好为与客户端代码交换的结构创建一个标准的指定内存布局的标准(这样,您就将责任推给客户端以提供适当的抽象)。

答案 1 :(得分:1)

使用extern struct myStruct structure;时,符号表中将有一个条目指向structure 并将其键入字符串structure

要获取其b成员的地址,只需执行以下操作:

struct myStruct *p = dlsym(handle, "structure");
if(!p) fail();
int *pb = &p->b;
相关问题