2008-09-17 3 views
3

Почему Leopard калечит некоторые символы с помощью $ non_lazy_ptr? Что еще более важно, что является лучшим методом для исправления неопределенных ошибок символов, потому что символ был искажен с помощью $ non_lazy_ptr?

ответ

5

От: Developer Connection - Indirect Addressing

Косвенная адресация является имя метода генерации кода, что позволяет символы, определенные в одном файле, чтобы ссылаться из другого файла, не требуя файл реферирования иметь явное знание расположения файла который определяет символ. Следовательно, определяющий файл может быть изменен независимо от файла ссылки. Косвенная адресация минимизирует количество мест, которые должны быть изменены динамическим компоновщиком, что облегчает совместное использование кода и повышает производительность.

Когда файл использует данные, определенные в другом файле, он создает ссылки на символы. Ссылка на символ идентифицирует файл, из которого импортирован символ, и ссылочный символ. Существует два типа ссылок на символы: нелазный и ленивый.

Ссылки на нелазные символы разрешены (привязаны к их определениям) динамическим компоновщиком при загрузке модуля. Символьная символьная ссылка - это, по сути, указатель на символ - кусок данных размера указателя. Компилятор генерирует нелазные ссылки на символы для символов данных или адресов функций.

Личные обозначения символов разрешаются динамическим компоновщиком при первом использовании (не во время загрузки). Последующие обращения к указанному символу переходят непосредственно к определению символа. Личные обозначения символов состоят из указателя символа и символьного заглушки, небольшого количества кода, который непосредственно разделяет и перескакивает через указатель символа. Компилятор генерирует ленивые ссылки на символы, когда он встречает вызов функции, определенной в другом файле.

3

В человеческом языке: компилятор генерирует заглушки с добавленным к ним $ non_lazy_ptr, чтобы ускорить связывание. Вероятно, вы видите, что функция Foo, ссылающаяся на _Foo $ non_lazy_ptr, не определена, или что-то в этом роде - это не одно и то же. Убедитесь, что символ фактически объявлен и экспортирован в объектные файлы/библиотеки, к которым вы привязываете свое приложение. По крайней мере, это была моя проблема, я также подумал, что это странная линкерная штука, пока я не обнаружил, что моя проблема была в другом месте - в Google есть несколько других возможных причин.

0

ranlib -c на библиотечный файл исправляет проблему

1

Если кто-то спотыкается та же проблема, у меня было:

Имел в файле заголовка extern NSString* const someString;, но забыл поставить его в файл реализации. as NSString* const [email protected]"someString";

Это решило проблему.

2
ranlib -c libwhatever.a 

является надежным решением проблемы. У меня была такая же проблема при создании библиотеки PJSIP для iOS. Эта сортировка библиотеки использует основанную на autoconf систему make, но нуждается в небольшой настройке на различные файлы, чтобы все было хорошо для iOS. В процессе выполнения этого мне удалось удалить строку ranlib в правиле для библиотек, а затем начал получать ошибку в ссылке моего проекта о _PJ_NO_MEMORY_EXCEPTION, на которую ссылается от _PJ_NO_MEMORY_EXCEPTION$non_lazy_ptr, который не определен.

Добавление строки ranlib обратно в файл библиотеки разрешило ее. Теперь моя полная запись для LIBS в правилах.mak is

$(LIB): $(OBJDIRS) $(OBJS) $($(APP)_EXTRA_DEP) 
    if test ! -d $(LIBDIR); then $(subst @@,$(subst /,$(HOST_PSEP),$(LIBDIR)),$(HOST_MKDIR)); fi 
    $(LIBTOOL) -o $(LIB) $(OBJS) 
    $(RANLIB) -c $(LIB) 

Надеюсь, что это поможет другим, а также пытается использовать общие внешние библиотеки UNIX с iPhone или iOS.

Смежные вопросы