7

As the title says... I'm interested in dlopen(). I understand this isn't allowed by the app store but I'm curious about this on iOS.

The issue I have is that I can create a .dylib file and I can load this file at runtime with the following code

char *dylibPath = "/Applications/myapp.app/mydylib2.dylib";

void *libHandle = dlopen(dylibPath, RTLD_NOW);
if (libHandle != NULL) {
    NSString * (*someMethod)() = dlsym(libHandle, "someMethod");
    if (someMethod != NULL)  {
        NSLog(someMethod());
    }
    dlclose(libHandle);
}

This is taken from here.

The problem I have is that if I change mydylib2.dylib, dlopen doesn't load the recompiled .dylib file. Instead, it resolves an old version of the function someMethod.

For example, if someMethod first returns @"Hello" and I change this to be @"Hello World" and recompile, the code above will always return @"Hello" until I restart the app in the simulator.

Do any know why this is the case? and suggest a workaround so the this .dylib can be reloaded at runtime?

Community
  • 1
  • 1
Eamonn Moloney
  • 487
  • 4
  • 12

1 Answers1

1

Looking at the man page for dlclose it looks like there are a couple of reasons why the library wouldn't be unloaded.

There are a couple of cases in which a dynamic library will never be unloaded: 1) the main executable links against it, 2) An API that does not supoort unloading (e.g. NSAddImage()) was used to load it or some other dynamic library that depends on it, 3) the dynamic library is in dyld's shared cache.

I suspect your issue is the "dyld shared cache." You could try running:

sudo update_dyld_shared_cache -force

after you've replaced the library (not sure if this is available on the iOS though).

Have you checked the return value of dlclose to see if it was successful or failed?

mttrb
  • 8,297
  • 3
  • 35
  • 57