On Aug 21, 2012, at 9:46 PM, AlexGray <[email protected]> wrote:
> I think the key line is this one
>
> 08-22 12:56:59.220 D/Mono (10563): DllImport error loading library:
> 'Cannot load library: link_image[1941]: 140 could not load needed library
> 'libQCAR.so' for 'libQCARWrapper.so' (load_library[1096]: Library
> 'libQCAR.so' not found)'.
>
> But i can't figure out why it cannot load libQCAR.so, as that is definately
> in the apk, in the same place as libQCARWrapper.so. So I would assume if it
> can find one, it can find the other.
You would think so, and you would be wrong.
Here's the problem: Android doesn't set LD_LIBRARY_PATH after the process is
forked, and thus ld.so doesn't know to check the
/data/data/your.package.name/lib directory; everything passed to dlopen() is
fully qualified.
Result: you have libQCARWrapper.so which has a link-time dependency on
libQCAR.so, but when you load libQCARWrapper.so dlopen(3) doesn't know to check
your app's lib directory to find libQCAR.so, so it fails the load.
What's the fix?
https://groups.google.com/forum/?fromgroups=#!topic/android-ndk/J3lzK4X--bM
> Yes, and this is the documented behaviour: you must load libraries in reverse
> dependency order explicitely. [0]
As the note says, you need to do one of two things:
(1) Find a "safe" function in libQCAR.so that you can P/Invoke AND INVOKE
before you call your libQCARWrapper.so function. When you invoke the libQCAR.so
function, libQCAR.so will be loaded, allowing your libQCARWrapper.so function
invocation to work.
(2) P/Invoke to dlopen(3) and explicitly dlopen("path/to/libQCAR.so"). The
downside is that you'll need to know what "path/to" is; given that anyone (and
everyone!) can modify Android, it's safest to use the
ApplicationInfo.NativeLibraryDir property [2]. The problem is that
ApplicationInfo.NativeLibraryDir was added in API9, so if you want to target
anything older you'll need to assume something; Mono for Android assumes that
native libraries are stored in Path.Combine(ApplicationInfo.DataDir, "lib")
(see e.g. the generated obj\Debug\android\src\mono\MonoPackageManager.java).
Of course, both approaches require that your native libraries have no circular
dependencies, as there's no way to individually load libraries if they have a
circular link-time dependency...
Finally, do note the cautionary note at the end of the above android-ndk forum
message:
> Some people have been playing with rpath to embed the full path of dependent
> libraries in the .so itself, but this is no[t] guaranteed to work (e.g. it
> will break if you move the app to the SD Card, because now the libraries are
> in a directory with a completely different path, most of it random iirc).
- Jon
[0] Though I do wish I knew _where_ this was "documented behavior", as [1]
doesn't find anything meaningful...
[1] https://www.google.com/search?q=dlopen+site%3Adeveloper.android.com
[2]
http://androidapi.xamarin.com/?link=P:Android.Content.PM.ApplicationInfo.NativeLibraryDir
_______________________________________________
Monodroid mailing list
[email protected]
UNSUBSCRIBE INFORMATION:
http://lists.ximian.com/mailman/listinfo/monodroid