【问题标题】:How to create a c++ class (.h and .cpp) in android studio?如何在 android studio 中创建一个 c++ 类(.h 和 .cpp)?
【发布时间】:2017-09-02 19:11:55
【问题描述】:

我正在学习使用 android NDK 并尝试创建一个原生 c++ 类(.h 和 .cpp)。我按照官方教程(https://developer.android.com/studio/projects/add-native-code.html)来实现这一点。我设法创建了一个简单的 c++ 类并从 java 调用它,没问题。

现在我想用一个什么都不做的构造函数创建我自己的 c++ 类(比如说一个 HellowWorld 类)。为此,我右键单击包含我已经工作的 JNI 包装器的 cpp 文件夹。

我创建了我的类并创建了一个默认构造函数并从我的 JNI 函数中调用它,但它在编译期间崩溃了:

错误:失败:构建失败并出现异常。

  • 出了什么问题: 任务 ':app:externalNativeBuildDebug' 执行失败。

    构建命令失败。 使用参数执行 'C:\Users\lucien.moor\AppData\Local\Android\Sdk\cmake\3.6.3155560\bin\cmake.exe' 时出错 {--build C:\Users\lucien.moor\Desktop\ tmp\MyApplication2\app.externalNativeBuild\cmake\debug\mips64 --target native-lib} [1/2] 构建CXX对象CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o [2/2] 链接 CXX 共享库 ........\build\intermediates\cmake\debug\obj\mips64\libnative-lib.so 失败: cmd.exe /C "cd . && C:\Users\lucien.moor\AppData\Local\Android\sdk\ndk-bundle\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe --target =mips64el-none-linux-android --gcc-toolchain=C:/Users/lucien.moor/AppData/Local/Android/sdk/ndk-bundle/toolchains/mips64el-linux-android-4.9/prebuilt/windows-x86_64 --sysroot=C:/Users/lucien.moor/AppData/Local/Android/sdk/ndk-bundle/platforms/android-21/arch-mips64 -fPIC -g -DANDROID -ffunction-sections -funwind-tables -fstack -protector-strong -no-canonical-prefixes -Wa,--noexecstack -Wformat -Werror=format-security -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -Wa ,--noexecstack -Wformat -Werror=format-security -O0 -fno-limit-debug-info -O0 -fno-limit-debug-info -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -Wl,--build-id - Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--no-undefined - Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -shared -Wl,-soname,libnative-lib.so -o ........\build\中间体\cmake\debug\obj\mips64\libnative-lib.so CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o -llog -lm "C:/Users/lucien.moor/ AppData/Local/Android/sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc++/4.9/libs/mips64/libgnustl_static.a" && cd ." CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o:在函数Java_he_1arc_myapplication2_MainActivity_stringFromJNI': C:\Users\lucien.moor\Desktop\tmp\MyApplication2\app\src\main\cpp/native-lib.cpp:10: undefined reference toHelloWorld::HelloWorld()' clang++.exe:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用) 忍者:构建停止:子命令失败。

  • 尝试: 使用 --stacktrace 选项运行以获取堆栈跟踪。使用 --info 或 --debug 选项运行以获得更多日志输出。

我认为链接 .h 和 .cpp 文件时出现问题。当我尝试内联实现我的构造函数时,它工作正常。它只是找不到 .cpp 实现。

这是我的 JNI native-lib.cpp 文件:

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

extern "C"
jstring
Java_he_1arc_myapplication2_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
HelloWorld t;
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}

这是我的 Helloworld.h:

#ifndef MYAPPLICATION2_HELLOWORLD_H
#define MYAPPLICATION2_HELLOWORLD_H


class HelloWorld {
public:
     HelloWorld();
};
#endif //MYAPPLICATION2_HELLOWORLD_H

这是我的 HelloWorld.cpp

#include "HelloWorld.h"
HelloWorld::HelloWorld() { }

当我打开这个文件时,android studio 告诉我“这个文件不是项目的一部分。请将它包含在适当的构建文件中(build.gradle、CMakeLists.txt 或 Android.mk 等) .) 并同步项目。”

那么,如何将这些可爱的 .h 和 .cpp 链接在一起?

【问题讨论】:

    标签: android c++ android-ndk android-studio-2.3


    【解决方案1】:

    我找到了解决办法!

    正如消息所建议的,我必须将我的文件添加到 CMakeLists.txt 中。头文件不是必需的,但 .cpp 文件必须添加到 CMakeLists.txt 中

    为了让链接器找到实现文件,我必须添加

    src/main/cpp/HelloWorld.cpp in my CMakeLists.txt
    

    这是完整的 CMakeLists 文件:

    cmake_minimum_required(VERSION 3.4.1)
    add_library( # Sets the name of the library.
             native-lib
    
             # Sets the library as a shared library.
             SHARED
    
             # Provides a relative path to your source file(s).
             # Associated headers in the same location as their source
             # file are automatically included.
             src/main/cpp/native-lib.cpp
             src/main/cpp/HelloWorld.cpp)
    find_library( # Sets the name of the path variable.
              log-lib
    
              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )
    target_link_libraries( # Specifies the target library.
                       native-lib
                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )
    

    【讨论】:

    • 谢谢,它有效。很奇怪需要将每个新类添加到 CKMakeLists
    【解决方案2】:
    public:
     HelloWorld();
    

    至少应该是这样

    public:
     HelloWorld()
       {
       //......
       }
    

    【讨论】:

    • 它可以工作,但这不是我想要实现的,我希望实现在 CPP 文件中。最终目标是使用已经编写好的 C++ 类(拆分为 .h/.cpp),我不想修改它们。而且我也认为在c++中做声明和实现不是一个好习惯
    • 对不起,我以为它来自您的 .cpp 文件。那么保持 .h 不变并将其放入 .cpp 文件中。
    • 这就是我对 HelloWorld::HelloWorld() { } 所做的,但编译器说它找不到实现。就像 HelloWorld.cpp 不是项目的一部分,编译器找不到它
    • 不,不是编译器。那只能来自链接器。通过在 cpp 文件中输入一些废话来检查它是否首先被编译。然后你应该得到编译器错误。
    • 是的,链接器失败:clang++.exe: error: linker command failed with exit code 1 (use -v to see invocation) ninja:构建停止:子命令失败。它还说:`C:\Users\lucien.moor\Desktop\tmp\MyApplication2\app\src\main\cpp/native-lib.cpp:10: undefined reference toHelloWorld::HelloWorld()'
    猜你喜欢
    • 1970-01-01
    • 2013-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多