Проблемы с компоновщиком в C ++ / ObjC - PullRequest
1 голос
/ 01 апреля 2011

Я портирую значительную кодовую базу на iOS.Упрощенная версия моего сценария выглядит следующим образом:

  • У меня есть библиотека C ++, построенная из командной строки.Я могу запустить код из симулятора iOS, поэтому я считаю, что он правильно построен.
  • У меня есть скелет iOS-приложения, созданный Xcode

Я хочу добавить запись в C ++библиотека.У меня есть метод trace (), который принимает fmt, ....Я компилирую этот .cpp, используя -x Objective-c++, код выглядит следующим образом:

void trace (const char* sFmt, ...)
{
    va_list args;
    va_start(args, sFmt);

    NSString* sFmt2 = [ NSString stringWithUTF8String: sFmt ];
    NSLogv(sFmt2, args);

    va_end(args);
}

Библиотека компилируется просто отлично.Однако, когда я пытаюсь связать приложение, я получаю ошибку компоновщика:

  ".objc_class_name_NSString", referenced from: literal-pointer@__OBJC@__cls_refs@NSString in lib.a(trace.o)

Это странно, потому что я могу использовать NSString и NSLog из файла .mm в самом проекте.Основы Фонда связаны между собой.Более того, просто для проверки, вместо вызова NSString из моей библиотеки, я добавил вспомогательный foobar () к .mm в проекте, который делает это

void foobar (const char* sFmt)
{
    NSLog([NSString stringWithUTF8String:sFmt]);
}

Когда это вызывается из функции библиотеки выше,это работает!

Все, что я читаю об ошибках такого рода, включает сценарий "только что обновил мой SDK", который не является моим случаем.Я начал заниматься iOS буквально два дня назад, я не изменил настройки проекта по умолчанию и т. Д.

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

Есть идеи?

Ответы [ 2 ]

0 голосов
/ 08 апреля 2011

Я смог исправить это, используя libtool вместо ld, передав ему -framework Foundation и передав -fobjc-abi-version=2 в gcc.

0 голосов
/ 01 апреля 2011

Ваш вывод компоновщика указывает, что вашей библиотекой, созданной из командной строки, является lib.a, что указывает мне, что это статическая библиотека. Я предполагаю, что, не будучи dylib, он не знает, как использовать dyloader для поиска пропущенных символов во время выполнения. В связи с этим я подозреваю, что проект iOS будет динамически связываться с этими системными библиотеками (даже если разработчики, не являющиеся ОС, не могут создавать динамические структуры), тогда как ваша статическая библиотека C ++ будет ожидать, что эти символы будут разрешены во время соединения.

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

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

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...