Я создал проект Android, содержащий код на С ++, использую CMake для компиляции с ++ и использую JNI для связи между с ++ и Java. В файле cpp
я использую miniLZO для сжатия файла. Вот код.
TestMiniLzo.cpp
#include <jni.h>
#include <string>
#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>
#include <iterator>
#include "minilzo.h"
std::vector<unsigned char> readFile(const std::string& file);
/* Work-memory needed for compression. Allocate memory in units
* of 'lzo_align_t' (instead of 'char') to make sure it is properly aligned.
*/
#define HEAP_ALLOC(var,size) \
lzo_align_t __LZO_MMODEL var [ ((size) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t) ]
static HEAP_ALLOC(wrkmem, LZO1X_1_MEM_COMPRESS);
std::string testMiniLzo() {
if (lzo_init() != LZO_E_OK) {
return "init failed";
}
std::vector<unsigned char> fileContents = readFile("/sdcard/testFile");
// compress with LZO1X-1
std::vector<unsigned char> compressOutput(fileContents.size() + fileContents.size() / 16 + 64 + 3);
lzo_uint outSize;
int r = lzo1x_1_compress(fileContents.data(), fileContents.size(), compressOutput.data(), &outSize, wrkmem);
if (r != LZO_E_OK) {
return "fail";
}
return "success";
}
std::vector<unsigned char> readFile(const std::string& file) {
std::ifstream input(file, std::ios::binary);
// copies all data into buffer
std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(input), {});
return buffer;
}
Это действительно сработало. Никаких ошибок не было. Но все изменилось после того, как я добавил аргумент CMake -DCMAKE_BUILD_TYPE:STRING=Release
в build.gradle(app)
.
externalNativeBuild {
cmake {
arguments "-DCMAKE_BUILD_TYPE:STRING=Release"
cppFlags ""
}
}
После добавления этого аргумента TestMiniLzo.cpp
, показанный выше, продолжал работать на эмуляторе Android x86, но приложение зависало на реальном устройстве Android (Nexus 6), которое имеет архитектуру arm. Вот ошибка.
06-23 10:03:40.962 11229 11229 F libc : Fatal signal 7 (SIGBUS), code 1, fault addr 0xaad38b85 in tid 11229 (y.myapplication)
06-23 10:03:40.963 261 261 W : debuggerd: handling request: pid=11229 uid=10109 gid=10109 tid=11229
06-23 10:03:41.033 11276 11276 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
06-23 10:03:41.033 11276 11276 F DEBUG : Build fingerprint: 'google/shamu/shamu:7.1.1/NGI77B/4345728:user/release-keys'
06-23 10:03:41.033 11276 11276 F DEBUG : Revision: '0'
06-23 10:03:41.033 11276 11276 F DEBUG : ABI: 'arm'
06-23 10:03:41.034 11276 11276 F DEBUG : pid: 11229, tid: 11229, name: y.myapplication >>> com.body.myapplication <<<
06-23 10:03:41.034 11276 11276 F DEBUG : signal 7 (SIGBUS), code 1 (BUS_ADRALN), fault addr 0xaad38b85
06-23 10:03:41.034 11276 11276 F DEBUG : r0 0a64696f r1 00000004 r2 a9abb2c0 r3 aad38b85
06-23 10:03:41.034 11276 11276 F DEBUG : r4 0000000c r5 aad38b7d r6 aad38b85 r7 beedd800
06-23 10:03:41.034 11276 11276 F DEBUG : r8 a9abb2a0 r9 a9abb2c0 sl 00000000 fp a9abb2c0
06-23 10:03:41.034 11276 11276 F DEBUG : ip 0000001c sp beedd7c8 lr aad38b70 pc ac71eab0 cpsr 60052430
06-23 10:03:41.037 11276 11276 F DEBUG :
06-23 10:03:41.037 11276 11276 F DEBUG : backtrace:
06-23 10:03:41.037 11276 11276 F DEBUG : #00 pc 00032ab0 /data/app/com.body.myapplication-1/lib/arm/libnative-lib.so (lzo1x_1_com
press+261)
06-23 10:03:41.037 11276 11276 F DEBUG : #01 pc 00031435 /data/app/com.body.myapplication-1/lib/arm/libnative-lib.so (_Z11testMin
iLzov+128)
06-23 10:03:41.038 11276 11276 F DEBUG : #02 pc 000325f7 /data/app/com.body.myapplication-1/lib/arm/libnative-lib.so (Java_com_bo
dy_myapplication_MainActivity_compressAndDecompressUsingLzo+26)
06-23 10:03:41.038 11276 11276 F DEBUG : #03 pc 00276b71 /data/app/com.body.myapplication-1/oat/arm/base.odex (offset 0x249000)
06-23 10:03:41.210 11253 11258 I art : Do partial code cache collection, code=28KB, data=30KB
06-23 10:03:41.210 11253 11258 I art : After code cache collection, code=28KB, data=30KB
06-23 10:03:41.210 11253 11258 I art : Increasing code cache capacity to 128KB
Просто, чтобы дать больше информации, вот мой CMakeLists.txt
.
CMakeLists.txt
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
add_subdirectory(minilzo-2.10 "${CMAKE_CURRENT_BINARY_DIR}/minilzo-build")
include_directories(minilzo-2.10)
include_directories(include)
add_library( # Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
TestMiniLzo.cpp
# Provides a relative path to your source file(s).
native-lib.cpp)
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
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)
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
# included in the NDK.
${log-lib}
minilzo)
Это /sdcard/testFile
, файл для сжатия. Он содержит только пять строк.
android
android
android
android
android
Почему происходит сбой приложения после добавления этого аргумента CMake? Как это исправить?