Structure Core Depth Camera Android App UnsatisfiedLinkError: cannot locate symbol "__sfp_handle_exceptions"
Structure Core Depth Camera Android App UnsatisfiedLinkError: cannot locate symbol "__sfp_handle_exceptions"
我正在尝试为深度相机 Structure Core 创建一个 android 应用程序。该产品附带 Android API,但问题是 api 文档非常简短且帮助不大。它有一个 APK 文件形式的预构建 Android 应用程序,以及 Windows、Linux 和 Android 的示例项目代码。问题是示例 Android 项目很旧。我设法构建它并安装到设备上,但该应用程序无法启动并出现错误 java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "__sfp_handle_exceptions"
。
因此,我尝试从头开始制作我的一个非常简单的应用程序,但最后不断弹出相同的错误(应用程序构建并安装成功):
2021-11-30 10:48:02.844 25827-25827/com.bridgewiz.structurecore.coreandroidtrial E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.bridgewiz.structurecore.coreandroidtrial, PID: 25827
java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "__sfp_handle_exceptions" referenced by "/data/app/com.bridgewiz.structurecore.coreandroidtrial-sHH5hFqRXfZv5IT1fQYgmg==/base.apk!/lib/arm64-v8a/libStructure.so"...
API 包含名为 libStructure.so
的核心库 .so 文件和不同示例项目(libDepthTester.so
、libPlayground.so
等)的实用程序库。
我的问题是,上面给出的错误是由于我的实现方面的问题造成的,还是在编译生产者提供的库 .so 文件时缺少某些内容?
.so文件的入口信息(aarch64-linux-android-readelf.exe)为
在我自己的项目中,app级gradle文件如下:
plugins {
id 'com.android.application'
id 'kotlin-android'
}
android {
compileSdk 31
defaultConfig {
applicationId "com.bridgewiz.structurecore.coreandroidtrial"
minSdk 27
targetSdk 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
arguments '-DANDROID_STL=c++_shared'
targets 'coreandroidtrial'
abiFilters 'arm64-v8a'
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
externalNativeBuild {
cmake {
path file('CMakeLists.txt')
version '3.10.2'
}
}
buildFeatures {
viewBinding true
}
sourceSets {
main {
jniLibs.srcDirs += ['libs']
}
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.2'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
对应的CMAKELists.txt文件为:
cmake_minimum_required(VERSION 3.10.2)
project("coreandroidtrial")
add_library( # Sets the name of the library.
coreandroidtrial
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/native-lib.cpp)
set_target_properties(coreandroidtrial PROPERTIES LINK_FLAGS "-Wl,-rpath,'$ORIGIN'")
find_library(
log-lib
log)
target_link_libraries( # Specifies the target library.
coreandroidtrial PRIVATE
${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI}/libDepthTester.so
${log-lib})
根据文档,需要的 AppInterface.h
本机文件如下:
#pragma once
/** These functions define the interface between cross-platform sample
application code and platform-specific wrappers. */
namespace AppInterface {
/** On desktop platforms this function is called in main() before
runUntilWindowClosed(). On Android it is called when the main activity
is created. */
void setup();
/** On desktop platforms this function is called in main() after
runUntilWindowClosed(). On Android it is called when the main activity
is destroyed. */
void teardown();
/** See Window::renderFrameInGLSurfaceViewContext(). */
void renderFrame(unsigned currentWidth, unsigned currentHeight, float scaleFactor);
/** See Window::updateMouseState(). */
void updateMouseState(bool down, int x, int y);
/** For applications that require Structure Core USB support. The argument
is a file descriptor from the Android UsbDeviceConnection API and should
be passed to ST::registerSensorByUSBFileDescriptor() or equivalent. */
void plugStructureCoreFileDescriptor(int fd);
/** For applications requiring CLI command support, this function will be processed before getting any GUI level setup*/
void cliCmdHandler(int argc, char **argv);
}
在我的默认 native-lib.cpp
文件中,只有 JNIEXPORT 函数定义及其对 ApplicationInterface 的各自调用:
#include <jni.h>
#include <string>
#include <thread>
#include "AppInterface.h"
extern "C" JNIEXPORT jstring JNICALL
Java_com_bridgewiz_structurecore_coreandroidtrial_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++ v4";
return env->NewStringUTF(hello.c_str());
}
extern "C"
JNIEXPORT void JNICALL
Java_com_bridgewiz_structurecore_coreandroidtrial_MainActivity_setupApp(JNIEnv *env, jobject thiz) {
AppInterface::setup();
}
extern "C"
JNIEXPORT void JNICALL
Java_com_bridgewiz_structurecore_coreandroidtrial_MainActivity_teardownApp(JNIEnv *env,
jobject thiz) {
AppInterface::teardown();
}
extern "C"
JNIEXPORT void JNICALL
Java_com_bridgewiz_structurecore_coreandroidtrial_MainActivity_renderFrame(JNIEnv *env,
jobject thiz,
jint current_width,
jint current_height,
jfloat scale_factor) {
AppInterface::renderFrame((unsigned)current_width, (unsigned)current_height, scale_factor);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_bridgewiz_structurecore_coreandroidtrial_MainActivity_updateMouseState(JNIEnv *env,
jobject thiz,
jboolean down,
jint x, jint y) {
AppInterface::updateMouseState(down, x, y);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_bridgewiz_structurecore_coreandroidtrial_MainActivity_plugStructureCoreFileDescriptor(
JNIEnv *env, jobject thiz, jint fd) {
AppInterface::plugStructureCoreFileDescriptor(fd);
}
您可能会看到项目文件和文件夹结构
通过一些搜索,看起来 __sfp_handle_exceptions
是 libstdc++
(来自 GCC)的一部分,而现代 Android NDK 附带 libc++
(Clang)。
最好的办法是向供应商索要针对 libc++
.
编译的库
如果他们不能或不会提供这样的东西,您可以尝试存根该函数或复制其实现 from here,但我不知道后者是否允许在许可方面使用。即便如此,也不能保证您最终会得到一个可用的应用程序。
我正在尝试为深度相机 Structure Core 创建一个 android 应用程序。该产品附带 Android API,但问题是 api 文档非常简短且帮助不大。它有一个 APK 文件形式的预构建 Android 应用程序,以及 Windows、Linux 和 Android 的示例项目代码。问题是示例 Android 项目很旧。我设法构建它并安装到设备上,但该应用程序无法启动并出现错误 java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "__sfp_handle_exceptions"
。
因此,我尝试从头开始制作我的一个非常简单的应用程序,但最后不断弹出相同的错误(应用程序构建并安装成功):
2021-11-30 10:48:02.844 25827-25827/com.bridgewiz.structurecore.coreandroidtrial E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.bridgewiz.structurecore.coreandroidtrial, PID: 25827
java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "__sfp_handle_exceptions" referenced by "/data/app/com.bridgewiz.structurecore.coreandroidtrial-sHH5hFqRXfZv5IT1fQYgmg==/base.apk!/lib/arm64-v8a/libStructure.so"...
API 包含名为 libStructure.so
的核心库 .so 文件和不同示例项目(libDepthTester.so
、libPlayground.so
等)的实用程序库。
我的问题是,上面给出的错误是由于我的实现方面的问题造成的,还是在编译生产者提供的库 .so 文件时缺少某些内容?
.so文件的入口信息(aarch64-linux-android-readelf.exe)为
在我自己的项目中,app级gradle文件如下:
plugins {
id 'com.android.application'
id 'kotlin-android'
}
android {
compileSdk 31
defaultConfig {
applicationId "com.bridgewiz.structurecore.coreandroidtrial"
minSdk 27
targetSdk 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
arguments '-DANDROID_STL=c++_shared'
targets 'coreandroidtrial'
abiFilters 'arm64-v8a'
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
externalNativeBuild {
cmake {
path file('CMakeLists.txt')
version '3.10.2'
}
}
buildFeatures {
viewBinding true
}
sourceSets {
main {
jniLibs.srcDirs += ['libs']
}
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.2'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
对应的CMAKELists.txt文件为:
cmake_minimum_required(VERSION 3.10.2)
project("coreandroidtrial")
add_library( # Sets the name of the library.
coreandroidtrial
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/native-lib.cpp)
set_target_properties(coreandroidtrial PROPERTIES LINK_FLAGS "-Wl,-rpath,'$ORIGIN'")
find_library(
log-lib
log)
target_link_libraries( # Specifies the target library.
coreandroidtrial PRIVATE
${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI}/libDepthTester.so
${log-lib})
根据文档,需要的 AppInterface.h
本机文件如下:
#pragma once
/** These functions define the interface between cross-platform sample
application code and platform-specific wrappers. */
namespace AppInterface {
/** On desktop platforms this function is called in main() before
runUntilWindowClosed(). On Android it is called when the main activity
is created. */
void setup();
/** On desktop platforms this function is called in main() after
runUntilWindowClosed(). On Android it is called when the main activity
is destroyed. */
void teardown();
/** See Window::renderFrameInGLSurfaceViewContext(). */
void renderFrame(unsigned currentWidth, unsigned currentHeight, float scaleFactor);
/** See Window::updateMouseState(). */
void updateMouseState(bool down, int x, int y);
/** For applications that require Structure Core USB support. The argument
is a file descriptor from the Android UsbDeviceConnection API and should
be passed to ST::registerSensorByUSBFileDescriptor() or equivalent. */
void plugStructureCoreFileDescriptor(int fd);
/** For applications requiring CLI command support, this function will be processed before getting any GUI level setup*/
void cliCmdHandler(int argc, char **argv);
}
在我的默认 native-lib.cpp
文件中,只有 JNIEXPORT 函数定义及其对 ApplicationInterface 的各自调用:
#include <jni.h>
#include <string>
#include <thread>
#include "AppInterface.h"
extern "C" JNIEXPORT jstring JNICALL
Java_com_bridgewiz_structurecore_coreandroidtrial_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++ v4";
return env->NewStringUTF(hello.c_str());
}
extern "C"
JNIEXPORT void JNICALL
Java_com_bridgewiz_structurecore_coreandroidtrial_MainActivity_setupApp(JNIEnv *env, jobject thiz) {
AppInterface::setup();
}
extern "C"
JNIEXPORT void JNICALL
Java_com_bridgewiz_structurecore_coreandroidtrial_MainActivity_teardownApp(JNIEnv *env,
jobject thiz) {
AppInterface::teardown();
}
extern "C"
JNIEXPORT void JNICALL
Java_com_bridgewiz_structurecore_coreandroidtrial_MainActivity_renderFrame(JNIEnv *env,
jobject thiz,
jint current_width,
jint current_height,
jfloat scale_factor) {
AppInterface::renderFrame((unsigned)current_width, (unsigned)current_height, scale_factor);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_bridgewiz_structurecore_coreandroidtrial_MainActivity_updateMouseState(JNIEnv *env,
jobject thiz,
jboolean down,
jint x, jint y) {
AppInterface::updateMouseState(down, x, y);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_bridgewiz_structurecore_coreandroidtrial_MainActivity_plugStructureCoreFileDescriptor(
JNIEnv *env, jobject thiz, jint fd) {
AppInterface::plugStructureCoreFileDescriptor(fd);
}
您可能会看到项目文件和文件夹结构
通过一些搜索,看起来 __sfp_handle_exceptions
是 libstdc++
(来自 GCC)的一部分,而现代 Android NDK 附带 libc++
(Clang)。
最好的办法是向供应商索要针对 libc++
.
如果他们不能或不会提供这样的东西,您可以尝试存根该函数或复制其实现 from here,但我不知道后者是否允许在许可方面使用。即便如此,也不能保证您最终会得到一个可用的应用程序。