Можно ли загрузить библиотеки GCed из программы, которая просто «поддерживает» ее? - PullRequest
2 голосов
/ 17 февраля 2012

У меня есть исполняемый файл командной строки, из которого я хотел бы иметь возможность загружать практически любую динамическую библиотеку, которая содержит классы Objective-C.В настройках проекта я указал, что моя программа поддерживает сборку мусора (без необходимости).Для этого я использую dlopen для загрузки библиотек, так как он глобально более гибкий, чем NSBundle (во-первых, и самое главное, он может загружать библиотеки, которые не входят в пакет).

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

Невозможно открыть / путь / к / объекту:dlopen (/ путь / к / lib, 2): подходящее изображение не найдено.Обнаружил:
/ path / to / lib: несоответствие возможностей GC

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

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

Сейчас у меня есть две версии моего исполняемого файла, но это подпункт.

Дополнительная информация : я нацеливаюсь только на Горного льва.Моя программа является универсальным двоичным файлом, и в настоящее время она выполняет перезапуск в качестве своего 32-разрядного аналога с использованием функции posix_spawn, однако там, похоже, нет флага, управляющего сборкой мусора.

Ответы [ 2 ]

0 голосов
/ 29 августа 2012

Я нашел решение своей проблемы. Среда выполнения Objective C имеет несколько переключателей, запускаемых переменными среды , включая OBJC_DISABLE_GC, которые могут отключать сборщик мусора, даже если исполняемый файл этого хочет. Этот параметр учитывается при загрузке новых изображений (см. gc_enforcer и о том, как он использует статическую переменную UseGC), поэтому отключение GC фактически повлияет на способ загрузки библиотек в процесс..

Таким образом, мое решение состоит в том, чтобы внедрить правильную логику сохранения / освобождения в мой исполняемый файл, но скомпилировать его с -fobjc-gc-only.Затем я пытаюсь загрузить библиотеку в обычном режиме;если это работает, все хорошо.Если это не так, я программно перезапускаю процесс с теми же аргументами, плюс OBJC_DISABLE_GC=YES в его среде, поэтому GC отключен, и библиотека успешно загружается на этот раз.

Этот фрагмент исключает обработку ошибок.1014 *

char disableGC[] = "OBJC_DISABLE_GC=YES";
// resets the current process with the given argv and enables the GC as per useGC
void respawn(char* const argv[], bool useGC)
{
    posix_spawnattr_t attributes;
    posix_spawnattr_init(&attributes);
    posix_spawnattr_setflags(&attributes, POSIX_SPAWN_SETEXEC)

    // build the environment variables array
    std::vector<char*> environment;
    for (char** environ_iter = environ; *environ_iter != 0; environ_iter++)
        environment.push_back(*environ_iter);

    // disable the GC if we need it off
    if (!useGC)
    {
        environment.push_back(disableGC);
    }

    environment.push_back(nullptr);

    pid_t child;
    posix_spawn(&child, argv[0], nullptr, &attributes, argv, environment.data());
}
0 голосов
/ 17 февраля 2012

Чтобы загрузить библиотеку «Сборка мусора», ваш исполняемый файл должен быть запущен в среде со сборщиком мусора. Вам нужно либо:

  • Всегда работать под GC
  • Определите, что для библиотеки требуется GC, и перезапустите ее с помощью GC, затем повторите попытку загрузки библиотеки. Вроде как, как Системные настройки перезапускаются для 32-битных панелей.
...