В C / C ++ можно экспортировать символ компоновщика для смещения внутри структуры? - PullRequest
0 голосов
/ 01 ноября 2018

В одном файле у меня есть структура вроде ...

struct t {
    int private;
    int public;
};

struct t s;

Один из способов получить доступ к другим объектным файлам s.public - поместить ...

struct t {
    int private;
    int public;
};

extern struct t s;

... в заголовочный файл, а другие файлы имеют ссылку s.public.

Я бы хотел избежать этого, потому что он фиксирует смещение между основанием s и основанием public в любых объектных файлах, которые ссылаются на s.public. Это означает, что эти файлы будут иметь неправильный адрес для public, если я когда-либо добавлю новый private2 после private, потребуется перекомпиляция.

Вместо этого я хотел бы найти способ экспортировать местоположение символа s.public как, возможно, непосредственно s_public_direct, а не как s со смещением в `public. Таким образом, другие файлы будут нуждаться только в заголовке ...

extern int s_public_direct;

... и не знал бы о структуре (или даже существовании) структуры, в которой public живет.

Есть ли способ экспортировать ссылку на символ для переменной, которая находится внутри структуры в C / C ++? Если нет, то есть ли элегантный способ решить эту проблему?

Обратите внимание, что это не ограниченная проблема, поэтому пометка private с помощью C ++ private: не изменит того факта, что ссылочный объектный файл все равно получит базовый адрес вмещающей структуры, а затем добавит смещение, чтобы добраться до public. Я действительно ищу какой-то синтаксис C / C ++, который говорит компилятору экспортировать символ переменной, которая находится внутри структуры. Или, может быть, способ объявить новый экспортируемый символ, такой как int s_public_direct, в качестве псевдонима для переменной внутри структуры.

1 Ответ

0 голосов
/ 01 ноября 2018

Самый простой способ сделать это - сохранить непрозрачный тип и функции доступа к экспорту для поля:

extern int get_t_public(struct t *);
extern void set_t_public(struct t *, int);

Это позволяет вам также экспортировать его только для чтения (определяя получение без набора) или множество других полезных вещей (применение некоторых ограничений к значению или кэширование зависящих от них вещей и аннулирование кэша, когда изменения стоимости и вещи должны быть пересчитаны.)

...