【问题标题】:Android JNI/C++: how to add properly a lib with .h and .cpp files?Android JNI/C++:如何正确添加带有 .h 和 .cpp 文件的库?
【发布时间】:2021-09-09 23:40:05
【问题描述】:

我是 Android Studio 中 JNI 的新手。

我创建了一个空的 Android Java/C++ 项目,现在我想添加第三方库的 .cpp 和 .h 文件以便在我的项目中编译它们。

这是我的项目的结构:

这是MainActivity.java的内容:

package com.example.testcpp;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import com.example.testcpp.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
        // Should I add here something like  System.loadLibrary("mythirdpartylib"); ???
    }

    private ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        // Example of a call to a native method
        TextView tv = binding.sampleText;
        tv.setText(stringFromJNI());
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();
}

这里是cpp文件夹根目录下的CMakeLists.txt文件内容:

cmake_minimum_required(VERSION 3.10.2)

# Declares and names the project.
project("testcpp")

add_library(native-lib SHARED native-lib.cpp )
find_library(log-lib log )
target_link_libraries( native-lib ${log-lib} )

add_subdirectory(mythirdpartylib)

我的 native-lib.cpp 中的代码:

#include <jni.h>
#include <string>

 #include "mythirdpartylib/a.h"

extern "C" JNIEXPORT jstring JNICALL

Java_com_example_testcpp_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {

    std::string hello = "Hello from C++";

// I would like to be able to call some code from mythirdpartylibrary, for example:
// std::string string2 = mythirdpartylib::getStringFromLib();

    return env->NewStringUTF(hello.c_str());
}

我的问题是当我点击文件夹 /mythordpartylib 中的任何 .cpp 文件时出现以下错误:

此文件不是项目的一部分。请将其包含在 适当的构建文件(build.gradle、CMakeLists.txt 或 Android.mk) 并同步项目

我在 /mythirdpartlib/CMakeLists.txt 中添加了这个:

cmake_minimum_required(VERSION 3.10.2)

project("testcpp") # Should I include this line in this subfolder ???
FILE(GLOB MyCSources *.cpp)

但这并不能解决问题。

那么,我应该如何在我的项目中正确包含 mythirdpartylib 呢?我应该怎么做才能在我的编译中包含这个库的 .cpp 文件?完成后,是否会在 libnative-lib.so 中编译thirdpartylib,或者我会有一个额外的 libmythirdpartylib.so 吗?

非常感谢您的帮助!

【问题讨论】:

    标签: java android c++ cmake java-native-interface


    【解决方案1】:

    如果lib只有cpp和h文件那么

    在 cmakelists.txt 中

    add_library(native-lib SHARED first_your_library.cpp native-lib.cpp)
    

    如果你想在这个 cmakelists 主目录中包含所有 cpp 文件和子文件夹

    include_directories(${CMAKE_SOURCE_DIR})
    file(GLOB_RECURSE SOURCES1 "mythirdpartylib/*.cpp") //here list all (cpp) files in mythirdpartylib folder in the root folder where CMakeLists.txt is situated
    
    
    
    add_library(native-lib SHARED PORT_DEF.h PATH_DEF.cpp share/request_callbacks.h ${SOURCES1} native-lib.cpp)
    

    如果头文件使用 cpp 文件,则包含 cpp 文件而不是头文件(将导致未定义的引用)如果它只是您添加的头文件,则编译顺序(您首先放置的文件也很重要)


    这是我完整的 CMaakeLists.txt 文件

        cmake_minimum_required(VERSION 3.4.1)
    
    # now build app's shared lib
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")
    include_directories(${CMAKE_SOURCE_DIR})
    file(GLOB_RECURSE SOURCES1 "share/*.cpp")
    
    
    
    add_library(art3dcadc SHARED PORT_DEF.h PATH_DEF.cpp share/request_callbacks.h ${SOURCES1} gl_code.cpp)
    #set(bass-lib "C:/Users/user/AndroidStudioProjects/SDL2-2.0.9/ART3DCAD/app/src/main/jniLibs/${ANDROID_ABI}/libbass.so")
    #add_library(bass-lib SHARED IMPORTED)
    
    # add lib dependencies
    target_link_libraries(art3dcadc
                          android
                          log 
                          EGL
                          GLESv2)
                          #-pthread -lv4l1 -lv4l2 -lv4lconvert)
    

    我看到你也有 lib 的 cmakelists,我不知道如何将一个与另一个合并,你可以像上面那样将库文件包含到主 cmakelists 中

    【讨论】:

    • 感谢您的回答。我不明白您的回答中有哪些文件:first_your_library.cpp、request_callbacks.h、PORT_DEF.h 和 PATH_DEF.cpp。你能提供更多细节吗?谢谢
    • 这些 request_callback.h、PORT_DEF.h 和 PATH_DEF.cpp 是我自己的项目文件,您从 cmakelists 中删除,它们供参考 [THE KEY WORD WAS ${SOURCES1} 包括所有 cpp 文件在指定的文件夹]。你有 a.cpp、b.cpp 和 c.cpp 所以首先打开 mythirdpartylib 文件夹中的 CMakeList.txt 并查看首先编译了哪些 cpp 文件(我分别假设 a、b、c)然后你的行应该看起来像 add_library(native- lib SHARED mythirdpartylib/a.cpp mythirdpartylib/b.cpp mythirdpartylib/c.cpp native-lib.cpp)
    • 如果您正确定义了 cmakelists.txt 并在其中定义了 project(prj_name)(作为库中的文件)然后 add_subdirectory("path") 然后 target_link_libraries( something prj_name)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多