Issue
I want to include two shared libraries liba.so and libb.so into my android application. Where function of libb.so is called from function in liba.so.
I have a Java class which calls native JNI Function as,
package com.test.myapplication;
public class MainActivity extends AppCompatActivity {
static{
System.loadLibrary(a);
System.loadLibrary(b);
}
public native void testSample();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
testSample();
}
}
My JNI file is
#include"a.h"
extern "C" void JNICALL Java_com_test_myapplication_MainActivity_testSample( JNIEnv* env, jobject thiz) {
a_foo();
}
a.cpp file which is part of my library liba.so is
#include"b.h"
void a_foo()
{
/* ..... code .....*/
b_foo();
/* ..... code .....*/
}
My b.cpp which is part of libb.so is
void b_foo()
{
/* ..... code .....*/
}
I want to include liba.so and libb.so as librares and not as source into my application. Both the libraries are built using android-ndk independently.
Solution
I am going to assume you have the Java/Android part figured out, as it has been many years since I have done any Java or Android (and even back then it was at university level). If you don't, I just read a short post about JNI that gave me a general idea on what actually needs to happen to get the Java code to work.
You need to build a new library from your JNI source code, and load that from your Java source using the System.loadLibrary() call. Let's call that libjni.so for now.
In CMake you do this via the following:
# jni.c is the file containing the **testSample** function with call to **a_foo()**
add_library(jni SHARED jni.c)
target_link_libraries(jni PRIVATE liba)
This will create a libjni.so file for you, which will link to liba.so. You can load that from your Java file like so:
System.loadLibrary(jni);
If liba.so is not built from the same CMake project, you need* to import it as a target, using CMake's find_library and add_library. There are plenty of examples online and in CMake Find modules. When it was built, it should have already specified its dependency (i.e. if you do ldd liba.so it should say that it links to libb.so). If it doesn't, and you can't fix this yourself, you can import libb.so as another target and append it to the target_link_library line above.
This should be enough to get you going with the shared object file you need for your Java/Android code to work, again assuming that the process of putting all the Java/Android bits together in CMake can be/has been achieved.
* You can actually use full paths to libraries in target_link_libraries calls but this isn't very idiomatic according to "Modern CMake" techniques.
EDIT
But how should I link libb to liba
Who builds liba and libb?
Are they sources of separate projects you maintain? If so, you need to alter your liba build system so it links to libb. Then rebuild liba and your JNI lib and your problem will go away.
If you don't maintain them yourself, you need to:
a) Import libb.so the same way liba.so is imported (find_library followed by add_library - links above) and then alter liba.so's target to have the libb.so target as a link dependency using set_target_properties
b) Raise an issue with liba.so's maintainer - if one library uses another, it is the job of the maintainer to fulfil this dependency, not the user.
Answered By - Pesho_T
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.