Получение адреса члена в структуре с динамическими библиотеками - PullRequest
0 голосов
/ 03 января 2019

Посмотрев на этот ответ: 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 и привести весь указатель к struct myStruct *. struct myStruct * capturedStructure = (struct myStruct*) dlsym(handle, "structure");

Однако есть ли способ получить адрес участника напрямую. Я думаю, я не могу сделать что-то вроде: int* c = (int*) dlsym(handle, "structure.b");

Поскольку dlsym позволяет человеку получить функцию или глобал самостоятельно (без заголовка), я надеюсь, что я также могу получить член без заголовка.

Ответы [ 2 ]

0 голосов
/ 03 января 2019

При extern struct myStruct structure; в таблице символов будет запись, указывающая на structure, и она будет привязана к строке structure.

Чтобы получить адрес ее члена b, простоделать:

struct myStruct *p = dlsym(handle, "structure");
if(!p) fail();
int *pb = &p->b;
0 голосов
/ 03 января 2019

адрес члена напрямую

Обычный способ выглядит следующим образом:

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 может быть согласованным, но чувствует себя плохо.Проще экспортировать структуру в код клиента.Возможно, в общем случае лучше создать стандарт, определяющий структуру памяти структуры, которую вы обмениваете с клиентским кодом (таким образом, вы возлагаете на клиентов ответственность за обеспечение надлежащей абстракции).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...