Что я делаю
При написании разделяемых библиотек для Linux я стараюсь обратить внимание на перемещение, видимость символов, GOT/PLT и т.д.
Когда это применимо, я пытаюсь избежать вызова PLT-заглушек, когда функции из одной библиотеки вызывают друг друга. Например, предположим, что общий объект предоставляет две публичные функции - foo()
и bar()
(любой из них может быть вызван пользователем). Однако функция bar()
также вызывает foo()
. Так что я делаю в этом случае следующее:
- Определите функции
_foo()
и_bar()
, которые имеют конфиденциальную видимость. - Определите слабые псевдонимы
foo()
иbar()
для_foo()
и_bar()
соответственно.
Таким образом, код в совместно используемом объекте никогда не использует слабые символы. Он вызывает непосредственно локальные функции. Например, когда вызывается _bar()
, он вызывает непосредственно _foo()
.
Но пользователи не знают о функциях _*
и всегда используют соответствующие слабые псевдонимы.
Как я это делаю
В Linux это достигается с помощью следующей конструкции:
extern __typeof (_NAME) NAME __attribute__(weak, alias("_NAME"));
Проблема
К сожалению, это не работает для OS X. У меня нет глубоких знаний об OS X или его двоичных форматах, поэтому я немного задумался и нашел несколько примеров слабых функций (например, этот), но это не совсем то же самое, что вы можете иметь слабый символ, но не слабый символ, который является псевдонимом для локальной функции DSO.
Возможное решение...
На данный момент я отключил эту функцию (которая реализована с использованием макросов), так что все символы являются глобальными и имеют видимость по умолчанию. Единственный способ, к которому я могу сейчас прийти, - иметь все функции _foo
с частной видимостью и иметь соответствующие функции foo
с видимостью по умолчанию и вызывать их "скрытые" копии.
Лучший способ?
Это, однако, требует хорошего фрагмента кода, который нужно изменить. Поэтому я бы предпочел не идти туда, если нет другого пути.
Итак, что закрывает альтернативу OS X или самый простой способ получить одну и ту же семантику/поведение?