Search code examples
androidandroid-ndkshared-librariessharedextern

Android NDK - 'extern' functions in library not found when app starts


I have built my Shared Library using NDK, that has few other libs in it. My lib has few 'extern' function defined. As it is a lib, those 'extern' functions are then declared in project (.cpp) file. I have an issue, where application builds just fine, and crashes on the device with the following error:

07-12 00:45:03.680: E/dalvikvm(2161): dlopen("/data/app-lib/org.libsdl.app-16/libRTEngine.so") failed: dlopen failed: cannot locate symbol "RTEngineSetup" referenced by "libRTEngine.so"...

This RTEngineSetup function is defined in my lib as : extern "C" void RTEngineSetup(); And then my application declares it like: void RTEngineSetup() { ... }

It seems like it can't link them together. This system works just fine on Desktops.

Here is an image of my code design: http://s14.postimg.org/s0r83u801/my_code.png

Here is how I build my libs (first part) and my Application (that includes my libs) (second part): http://ann-tech.com/lib_Android.txt

Please, if anyone has any idea why 'extern' definition () is not linked with it's declaration in application's .cpp file, please let me know. Wasted 2 days now.

Thanks for your time.


Solution

  • Alex!

    This is amazing! thank you very much. I am new to NDK and Android coding so had to hack for 3 days straight. When you said to use dlsym(), I had no idea what i it is. But I have figured it out and everything works just perfect now.

    Solution: If your Library has C++ functions (defined) as extern - extern void Update(); for example, and you are trying to link this library to your application, where you want to (declare) those functions like that: void Update() { ... }, you have to, in your library C++ code, add this code:

    //Library file pointer
    void *handle;
    handle = dlopen( "lib/libRTApp.so", RTLD_LOCAL | RTLD_LAZY );
    
    // New names for functions you are linking to
    void ( *RTUpdate )( void ), ( *RTClose )( void );
    
    // Assigning function to a pointer
    *( void ** ) ( &RTUpdate ) = dlsym( handle, "RTAppUpdate" );
    *( void ** ) ( &RTClose ) = dlsym( handle, "RTAppClose" );
    
    // Free the memory!
    dlclose( handle );  
    

    Thanks a lot Alex Cohn! You have saved me.