Ответ 1
Это действительно невозможно, мне жаль говорить. Это связано с тем, как работают статические библиотеки. Статическая библиотека - это нечто большее, чем совокупность объединенных файлов *.o
, но динамическая библиотека - загружаемое двоичное изображение, как и исполняемый файл.
Предположим, у вас есть четыре файла,
- common.c определяет
common
, который "private" - fn1.c определяет
fn1
, который вызываетcommon
. - fn2.c определяет
fn2
, который вызываетcommon
. - other.c определяет
other
.
В динамической библиотеке компоновщик объединяет все в один большой кусок кода. Библиотека экспортирует other
, fn1
и fn2
. Вам нужно загрузить всю библиотеку или ничего из нее, но две программы могут загружать ее, не помещая несколько копий в память. Точка входа в common
просто отсутствует в таблице символов - вы не можете вызывать ее из-за пределов библиотеки, потому что компоновщик не может ее найти.
Обратите внимание, что приложение и общая библиотека имеют, по существу, один и тот же формат: приложение в основном является общей библиотекой, которая экспортирует только один символ, main
. (Это не совсем так, но близко.)
В статической библиотеке компоновщик никогда не запускается. Все файлы скомпилируются в файлы *.o и помещаются в архив библиотеки *.a. Внутренние ссылки не будут решены.
Предположим, что ваше приложение вызывает fn1
. Компилятор видит неразрешенный вызов fn1
, а затем просматривает библиотеки. Он находит определение для fn1
в fn1.o. Затем компоновщик замечает неразрешенный вызов common
, поэтому он выглядит обычным. Эта программа не получит код из fn2.c или other.c, потому что он не использует определения из этих файлов.
Статические библиотеки очень старые, и у них нет функций динамических библиотек. Вы можете представить себе статическую библиотеку, как в основном zip файл, полный скомпилированного исходного кода, в отличие от динамической библиотеки, которая связана между собой. Никто никогда не удосужился расширить формат архива, чтобы добавить видимость символов. Когда вы связываетесь со статической библиотекой, вы получаете такой же результат, как если бы вы добавили исходный код библиотеки в свою программу.
Краткая версия: Динамическая библиотека имеет одну таблицу символов всех экспортированных символов, но ни один из частных символов. Точно так же объектный файл имеет список всех его символов extern
, но ни один из static
. Но статическая библиотека не имеет таблицы символов, это просто архив. Таким образом, нет механизма, чтобы сделать код закрытым для статической библиотеки (кроме определения объектов static
, но это не работает для классов Objective-C).
Если бы мы знали, почему вы пытались это сделать, возможно, мы могли бы дать вам предложение. (Является ли это для безопасности? Имя столкновения? Все эти вопросы имеют решения.)