Как скрыть объекты в объективе -c библиотекой

Я пытаюсь создать статическую библиотеку, написанную на Objective -C. Я хотел бы скрыть все детали реализации от потребителей этой библиотеки. В этом примере объект «OneThing» использует другие функции, внутренние для библиотеки, включая «SecretThing», который может использоваться многими вещами внутри библиотеки (и не может быть скрыт внутри OneThing ). Однако я не хочу, чтобы пользователи библиотеки видели, что OneThing использует SecretThing или что SecretThing вообще существует, даже если они ковыряются в файле.a.

@interface OneThing
+ (void) do;
@end
@interface SecretThing
+ (void) undo;
@end
@implementation OneThing
+ (void) do
{
    [SecretThing undo];
}
@end
@implementation SecretThing
+ (void) undo { }
@end

Если мы скомпилируем это и проверим таблицу символов:

% cc -c onething.m
% nm onething.o | grep Thing
0000000000000000 t +[OneThing do]
00000000000002f8 s +[OneThing do].eh
0000000000000040 t +[SecretThing undo]
0000000000000320 s +[SecretThing undo].eh
0000000000000078 S _OBJC_CLASS_$_OneThing
0000000000000050 S _OBJC_CLASS_$_SecretThing
00000000000000a0 S _OBJC_METACLASS_$_OneThing
00000000000000c8 S _OBJC_METACLASS_$_SecretThing
0000000000000128 s l_OBJC_$_CLASS_METHODS_OneThing
00000000000001d8 s l_OBJC_$_CLASS_METHODS_SecretThing
0000000000000190 s l_OBJC_CLASS_RO_$_OneThing
0000000000000240 s l_OBJC_CLASS_RO_$_SecretThing
0000000000000148 s l_OBJC_METACLASS_RO_$_OneThing
00000000000001f8 s l_OBJC_METACLASS_RO_$_SecretThing
% 

Как и следовало ожидать, мы видим, что OneThing и SecretThing одинаково уязвимы. Теперь было бы здорово каким-то образом разрешить внутреннее -в -использование библиотеки -SecretThing и выставить OneThing только внешнему миру. Что я хотел сделать, так это (выбрать только один метод, чтобы попытаться управлять):

% ld -r onething.o -exported_symbol "+[OneThing do]" -o onlyonething.o

Я надеялся, что это пометит "+[OneThing do]" как тип "T", (Text global ), который затем выдержит "полосу". Это не. Это беспокоит меня, потому что я думал, что это работало в какой-то момент времени, и, возможно, когда я обновил цепочки инструментов, я получил новую версию ld ("ld -v" == ld64 -133.3 ), которая работает по-другому..

У меня нет идей, кроме как передать исходный код компоновщику и написать свой собственный новый флаг, чтобы делать то, что я хочу. Я надеюсь, что я просто глуп, и есть что-то, что я не понимаю, что делает это проще.


В ответах было высказано предположение, что это было бы принципиально невозможно, потому что вам нужна вся информация о связях, доступная во время выполнения, для отправки метода. Я считаю, что этот эксперимент доказывает, что это не так.

# Move OneThing and SecertThing into their own files, with their own.h
% cat c_api.m
#include "OneThing.h"

void one_thing_do()
{
    [OneThing do];
}
% cc -c c_api.c
% cat main.m
int main(int argc, char**argv)
{
    extern void one_thing_do();

    one_thing_do();
}
% cc main.m c_api.o onething.o secretthing.o -framework Foundation
%./a.out
% ( runs to completion, no errors )

Теперь мы пытаемся скрыть части, которые мы не хотим, чтобы мир увидел:

% ld -r c_api.o onething.o secretthing.o -o strip_c_api.o -exported_symbol "_one_thing_do"
% strip -x c_strip_c_api.o
% nm strip_c_api.o
0000000000000118 s EH_Frame1
0000000000000098 s EH_Frame1
00000000000000d8 s EH_Frame1
                 U __objc_empty_cache
                 U __objc_empty_vtable
                 U _objc_msgSend
0000000000000000 T _one_thing_do
0000000000000130 s func.eh
00000000000000f0 s func.eh
00000000000000b0 s func.eh
0000000000000020 t l001
0000000000000060 t l002
0000000000000170 s l003
0000000000000190 s l004
00000000000001d8 s l005
0000000000000220 s l006
0000000000000240 s l007
0000000000000288 s l008
00000000000002f0 s l009
0000000000000318 s l010
0000000000000340 s l011
0000000000000368 s l012
% clang main.m strip_c_api.o -framework Foundation
%./a.out
% nm a.out
0000000100001280 S _NXArgc
0000000100001288 S _NXArgv
0000000100001298 S ___progname
0000000100000000 T __mh_execute_header
                 U __objc_empty_cache
                 U __objc_empty_vtable
0000000100001290 S _environ
                 U _exit
0000000100000db0 T _main
                 U _objc_msgSend
0000000100000de0 T _one_thing_do
0000000100001000 s _pvars
                 U dyld_stub_binder
0000000100000d70 T start
5
задан mtoy 26 July 2012 в 20:38
поделиться