Я удивлен тем, как мало информации существует для этого. Многие решения там не были доступны на MacOS / iOS. Другие по-прежнему были только о том, чтобы получить путь к текущему исполняемому файлу, и не имели никакого отношения к дескриптору.
После ТОННА поиска я наконец-то наткнулся на некоторые ресурсы, в которых говорилось, что нужно перебрать все загруженные изображения, используя _dyld_image_count()
и _dyld_get_image_name()
. Сначала я решил против этого, так как это не казалось неоправданно медленным способом ведения дел.
В конце концов, я решил пройтись по всем загруженным изображениям, так как это было единственное реальное решение, с которым я столкнулся. Я гуглил по примерам и не смог найти ни одного учебника по теме. Однако я натолкнулся на библиотеку C ++ с открытым исходным кодом, которая реализовала эту функциональность (найдено здесь ).
Я перевел его в обычный C и избавился от некоторых лишних вещей (таких как снятие ручки). В процессе тестирования я заметил, что нужная мне библиотека всегда была последней в списке (я думаю, что она хранит их в том порядке, в котором они были загружены, и, поскольку моя библиотека не является системной, она будет одной из последние загружены). Это гарантировало низкую производительность (по отношению к компьютеру - для человека это было бы почти мгновенно). Итак, я выполнил хитрую оптимизацию, которая начала поиск с конца списка, а не с начала.
Это окончательный код моего решения:
// NOT a thread safe way of doing things
NSString *pathFromHandle(void* handle)
{
// Since we know the image we want will always be near the end of the list, start there and go backwards
for (uint32_t i = (_dyld_image_count() - 1); i >= 0; i--)
{
const char* image_name = _dyld_get_image_name(i);
// Why dlopen doesn't effect _dyld stuff: if an image is already loaded, it returns the existing handle.
void* probe_handle = dlopen(image_name, RTLD_LAZY);
dlclose(probe_handle);
if (handle == probe_handle)
{
return [NSString stringWithUTF8String:image_name];
}
}
return NULL;
}
Важно отметить, что это решение не является поточно-ориентированным, поскольку _dyld_image_count()
и _dyld_get_image_name()
по своей сути не являются поточно-ориентированными. Это означает, что любой другой поток может загрузить / выгрузить изображение и оказать негативное влияние на наш поиск.
Кроме того, ресурс , который я использовал, задавался вопросом, почему dlopen
не оказал влияния на _dyld_image_count()
. Это связано с тем, что если изображение уже загружено, dlopen
не загружает новый экземпляр изображения, а скорее возвращает существующий дескриптор для него.