Structure Core Depth Camera Android App UnsatisfiedLinkError: cannot locate symbol "__sfp_handl

Posted

技术标签:

【中文标题】Structure Core Depth Camera Android App UnsatisfiedLinkError: cannot locate symbol "__sfp_handle_exceptions"【英文标题】: 【发布时间】:2022-01-06 23:32:11 【问题描述】:

我正在尝试为深度相机结构核心创建一个 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.solibPlayground.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);

您可能会看到项目文件和文件夹结构

【问题讨论】:

【参考方案1】:

经过一番搜索,__sfp_handle_exceptions 似乎是 libstdc++ 的一部分(来自 GCC),而现代 Android NDK 附带 libc++(Clang)。 最好的办法是向供应商索要针对 libc++ 编译的库。

如果他们不能或不会提供这样的东西,您可以尝试对函数进行存根或复制其实现from here,但我不知道后者是否允许许可。即便如此,也不能保证您最终会得到一个可以工作的应用程序。

【讨论】:

这是有道理的。但 readelf 输出显示需要 libc++_shared.so,而不是 libstdc++。这正常吗?

以上是关于Structure Core Depth Camera Android App UnsatisfiedLinkError: cannot locate symbol "__sfp_handl的主要内容,如果未能解决你的问题,请参考以下文章

translation of the paper sequence and structure conservation in a protein core

请问英伟达 NVIDIA Tensor Core与structure sparse对于科学计算是不是?

iOS-Core-Animation-Advanced-Techniques

iOS-Core-Animation-Advanced-Techniques

[HDU]6356 Glad You Came(ST表)

HDOJ:6356-Glad You Came(线段树剪枝)