如何在 android studio 中创建 c++ class(.h 和 .cpp)?
How to create a c++ class (.h and .cpp) in android studio?
我正在学习使用 android NDK 并尝试创建原生 C++ class(.h 和 .cpp)。我按照官方教程(https://developer.android.com/studio/projects/add-native-code.html)来实现这一点。我设法创建了一个简单的 c++ class 并从 java 调用它,没问题。
现在我想创建我自己的 c++ class(假设是一个 HellowWorld class),只使用一个什么也不做的构造函数。为此,我右键单击我的 cpp 文件夹,其中包含我已经在工作的 JNI 包装器。
我创建了我的 class 并创建了一个默认构造函数并从我的 JNI 函数中调用它,但它在编译期间崩溃了:
Error:FAILURE: Build failed with an exception.
出了什么问题:
任务“:app:externalNativeBuildDebug”执行失败。
Build command failed.
Error while executing 'C:\Users\lucien.moor\AppData\Local\Android\Sdk\cmake.6.3155560\bin\cmake.exe' with arguments {--build C:\Users\lucien.moor\Desktop\tmp\MyApplication2\app.externalNativeBuild\cmake\debug\mips64 --target native-lib}
[1/2] Building CXX object CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o
[2/2] Linking CXX shared library ........\build\intermediates\cmake\debug\obj\mips64\libnative-lib.so
FAILED: 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\intermediates\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: In function Java_he_1arc_myapplication2_MainActivity_stringFromJNI':
C:\Users\lucien.moor\Desktop\tmp\MyApplication2\app\src\main\cpp/native-lib.cpp:10: undefined reference to
HelloWorld::HelloWorld()'
clang++.exe: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.
尝试:
运行 使用 --stacktrace 选项获取堆栈跟踪。 运行 使用 --info 或 --debug 选项以获得更多日志输出。
我认为 link 处理 .h 和 .cpp 文件时出现问题。当我尝试内联实现我的构造函数时,它工作正常。它只是找不到 .cpp 实现。
这是我的 JNI 本机-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工作室告诉我"This file is not part of the project. Please include it in the appropriate build file (build.gradle, CMakeLists.txt or Android.mk etc.) and sync the project."
所以,我如何 link 这些可爱的 .h 和 .cpp 在一起?
public:
HelloWorld();
至少应该是
public:
HelloWorld()
{
//......
}
我找到了解决方案!
正如消息所建议的那样,我必须在 CMakeLists.txt 中添加我的文件。不需要头文件,但必须在 CMakeLists.txt
中添加 .cpp 文件
为了让链接器找到实现文件,我不得不添加
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} )
我正在学习使用 android NDK 并尝试创建原生 C++ class(.h 和 .cpp)。我按照官方教程(https://developer.android.com/studio/projects/add-native-code.html)来实现这一点。我设法创建了一个简单的 c++ class 并从 java 调用它,没问题。
现在我想创建我自己的 c++ class(假设是一个 HellowWorld class),只使用一个什么也不做的构造函数。为此,我右键单击我的 cpp 文件夹,其中包含我已经在工作的 JNI 包装器。
我创建了我的 class 并创建了一个默认构造函数并从我的 JNI 函数中调用它,但它在编译期间崩溃了:
Error:FAILURE: Build failed with an exception.
出了什么问题: 任务“:app:externalNativeBuildDebug”执行失败。
Build command failed. Error while executing 'C:\Users\lucien.moor\AppData\Local\Android\Sdk\cmake.6.3155560\bin\cmake.exe' with arguments {--build C:\Users\lucien.moor\Desktop\tmp\MyApplication2\app.externalNativeBuild\cmake\debug\mips64 --target native-lib} [1/2] Building CXX object CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o [2/2] Linking CXX shared library ........\build\intermediates\cmake\debug\obj\mips64\libnative-lib.so FAILED: 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\intermediates\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: In function
Java_he_1arc_myapplication2_MainActivity_stringFromJNI': C:\Users\lucien.moor\Desktop\tmp\MyApplication2\app\src\main\cpp/native-lib.cpp:10: undefined reference to
HelloWorld::HelloWorld()' clang++.exe: error: linker command failed with exit code 1 (use -v to see invocation) ninja: build stopped: subcommand failed.尝试: 运行 使用 --stacktrace 选项获取堆栈跟踪。 运行 使用 --info 或 --debug 选项以获得更多日志输出。
我认为 link 处理 .h 和 .cpp 文件时出现问题。当我尝试内联实现我的构造函数时,它工作正常。它只是找不到 .cpp 实现。
这是我的 JNI 本机-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工作室告诉我"This file is not part of the project. Please include it in the appropriate build file (build.gradle, CMakeLists.txt or Android.mk etc.) and sync the project."
所以,我如何 link 这些可爱的 .h 和 .cpp 在一起?
public:
HelloWorld();
至少应该是
public:
HelloWorld()
{
//......
}
我找到了解决方案!
正如消息所建议的那样,我必须在 CMakeLists.txt 中添加我的文件。不需要头文件,但必须在 CMakeLists.txt
中添加 .cpp 文件为了让链接器找到实现文件,我不得不添加
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} )