如何在Android应用程序的cmake中使用两个预构建的相互依赖的共享库

我想在我的Android应用程序中包含两个共享库liba.solibb.so。从libb.so中的函数中调用liba.so的函数。

我有一个Java类,它调用本地JNI函数为

 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();
    }
  }

我的JNI文件是

#include"a.h"

extern "C" void JNICALL Java_com_test_myapplication_Mainactivity_testSample( JNIEnv* env,jobject thiz) {
    a_foo();
}
属于我的库liba.so的

a.cpp文件是

#include"b.h"
void a_foo()
    {
         /* ..... code .....*/
         b_foo();
         /* ..... code .....*/
    }

我的b.cpp是libb.so的一部分

void b_foo()
    {
         /* ..... code .....*/
    }

我想将liba.so和libb.so作为librares而不是作为源添加到我的应用程序中。这两个库都是使用android-ndk独立构建的。

ci123042908 回答:如何在Android应用程序的cmake中使用两个预构建的相互依赖的共享库

我将假设您已经掌握了Java / Android部分,因为自从我完成任何Java或Android以来已经有很多年了(甚至在那时还处于大学水平)。如果您不这样做,我只是读了一篇有关JNI的short post,使我对使Java代码正常工作实际需要做的事情有一个大致的了解。

您需要从JNI源代码构建新的库,并使用 System.loadLibrary()调用从Java源中加载该库。现在我们称其为 libjni.so

在CMake中,您可以通过以下方式进行操作:

# 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)

这将为您创建一个 libjni.so 文件,该文件将链接到 liba.so 。您可以像这样从Java文件加载该文件:

System.loadLibrary(jni);

如果 liba.so 不是从同一CMake项目构建的,则需要*使用CMake的find_libraryadd_library将其导入为目标。在线和CMake 查找模块中都有大量示例。构建它时,它应该已经指定了它的依赖关系(即,如果您执行ldd liba.so,它应该说它链接到 libb.so )。如果没有,您也无法自己解决此问题,则可以将 libb.so 导入为另一个目标,并将其附加到上面的 target_link_library 行中。

这足以让您处理Java / Android代码正常工作所需的共享对象文件,再次假设可以实现将所有Java / Android位放到CMake中的过程。


*实际上,您可以在 target_link_libraries 调用中使用库的完整路径,但是根据“现代CMake”技术,这并不是很习惯。


编辑

  

但是我应该如何将libb链接到liba

谁构建 liba libb

它们是您维护的单独项目的来源吗?如果是这样,则需要更改您的 liba 构建系统,使其链接到 libb 。然后重建 liba ,您的JNI lib和问题将消失。

如果您自己不维护它们,则需要:

a)导入 libb.so 的方式与导入 liba.so 的方式相同({find_library,后跟add_library-上面的链接),然后使用set_target_properties

更改 liba.so 的目标,以将 libb.so 目标作为链接依赖项

b)引起 liba.so 的维护者的问题-如果一个库使用另一个库,则维护者的工作就是满足这种依赖性,而不是用户。

本文链接:https://www.f2er.com/3076183.html

大家都在问