使用本机lib(仅限C,没有C++),并且找不到实现

Using native lib (C only, no C++), and No Implementation Found

本文关键字:C++ 实现 找不到 没有 lib 本机 仅限      更新时间:2023-10-16

尝试在android和AFAIK上使用这个库作为opus,链接和.so看起来不错。

调用C函数时出错(我遵循了这些内部结构)

D/OpusRecorder( 1964): Start recording!
E/art     ( 1964): No implementation found for int com.droidkit.opus.OpusLib.startRecord(java.lang.String) (tried Java_com_droidkit_opus_OpusLib_startRecord and Java_com_droidkit_opus_OpusLib_startRecord__Ljava_lang_String_2)
E/AndroidRuntime( 1964): FATAL EXCEPTION: Thread-8227
E/AndroidRuntime( 1964): Process: com.borneo.speech, PID: 1964
E/AndroidRuntime( 1964): java.lang.UnsatisfiedLinkError: No implementation found for int com.droidkit.opus.OpusLib.startRecord(java.lang.String) (tried Java_com_droidkit_opus_OpusLib_startRecord and Java_com_droidkit_opus_OpusLib_startRecord__Ljava_lang_String_2)
E/AndroidRuntime( 1964):    at com.droidkit.opus.OpusLib.startRecord(Native Method)
E/AndroidRuntime( 1964):    at com.borneo.speech.OpusRecorder.run(OpusRecorder.java:439)
W/ActivityManager(  724):   Force finishing activity 1 com.borneo.speech/.Speech_API_Activity

.so封装在apk 中

函数存在于Type="T"的.so中。。。

aar$ nm -D libopus.so | head
000084c1 T Java_com_droidkit_opus_OpusLib_closeOpusFile
000084c5 T Java_com_droidkit_opus_OpusLib_isOpusFile
00008491 T Java_com_droidkit_opus_OpusLib_openOpusFile
00008471 T Java_com_droidkit_opus_OpusLib_readOpusFile
00008489 T Java_com_droidkit_opus_OpusLib_seekOpusFile
00008145 T Java_com_droidkit_opus_OpusLib_startRecord ***

---CLang详细信息---

在C:中的实现

audio.c

#include "com_droidkit_opus_OpusLib.h"   <-- from the Java class=com.droidkit.opus.OpusLib via javah

//每@Nicklas 的转速

JNIEXPORT jint JNICALL Java_com_droidkit_opus_OpusLib_startRecord(JNIEnv *env, jobject javaThis, jstring path) {
    const char *pathStr = (*env)->GetStringUTFChars(env, path, 0);
    int result = initRecorder(pathStr);
    if (pathStr != 0) {
        (*env)->ReleaseStringUTFChars(env, path, pathStr);
    }
    return result;
}

c标头。。。

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_droidkit_opus_OpusLib */
#ifndef _Included_com_droidkit_opus_OpusLib
#define _Included_com_droidkit_opus_OpusLib
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_droidkit_opus_OpusLib
 * Method:    startRecord
 * Signature: (Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_com_droidkit_opus_OpusLib_startRecord
  (JNIEnv *, jobject, jstring);
/*
 * Class:     com_droidkit_opus_OpusLib
 * Method:    writeFrame
 * Signature: (Ljava/nio/ByteBuffer;I)I
 */
JNIEXPORT jint JNICALL Java_com_droidkit_opus_OpusLib_writeFrame
  (JNIEnv *, jobject, jobject, jint);
/*
 * Class:     com_droidkit_opus_OpusLib
 * Method:    stopRecord
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_droidkit_opus_OpusLib_stopRecord
  (JNIEnv *, jobject);
/*
 * Class:     com_droidkit_opus_OpusLib
 * Method:    isOpusFile
 * Signature: (Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_com_droidkit_opus_OpusLib_isOpusFile
  (JNIEnv *, jobject, jstring);
...
#ifdef __cplusplus
}
#endif
#endif

===JAVA详细信息调用C===

===已编辑===Java本机声明。

/**
 * OpusLib native binding
 */
public class OpusLib {
    static {
        System.loadLibrary("opus");
    }
    /**
     * Starting opus recording
     *
     * @param path path to file
     * @return non zero if started player
     */
    public native int startRecord(String path);

    /**
     * Writing audio frame to encoder
     *
     * @param frame buffer with sound in 16 bit mono PCM 16000 format
     * @param len   len of data
     * @return not null if successful
     */
    public native int writeFrame(ByteBuffer frame, int len);
    /**
     * Stopping record
     */
    public native void stopRecord();
    /**
     * Checking Opus File format
     *
     * @param path path to file
     * @return non zero if opus file
     */
    public native int isOpusFile(String path);
    /**
     * Opening file
     *
     * @param path path to file
     * @return non zero if successful
     */
    public native int openOpusFile(String path);
    /**
     * Seeking in opus file
     *
     * @param position position in file
     * @return non zero if successful
     */
    public native int seekOpusFile(float position);
    /**
     * Closing opus file
     */
    public native void closeOpusFile();
    /**
     * Reading from opus file
     *
     * @param buffer
     * @param capacity
     */
    public native void readOpusFile(ByteBuffer buffer, int capacity);
    /**
     * Is playback finished
     *
     * @return non zero if playback is finished
     */
    public native int getFinished();
    /**
     * Read block size in readOpusFile
     *
     * @return block size in bytes
     */
    public native int getSize();
    /**
     * Offset of actual sound for playback
     *
     * @return offset
     */
    public native long getPcmOffset();
    /**
     * Total opus pcm duration
     *
     * @return pcm duration
     */
    public native long getTotalPcmDuration();
}
        try {
            opus = new OpusLib();
        }catch(UnsatisfiedLinkError ulx) {
            Log.e(LTAG, "Illegal native Load: " + ulx.getMessage());
        }
...
public class OpusLib {
    static {
        System.loadLibrary("opus");
    }   

AFAIK,库加载正常

不满意的链接Excp发生在下面的最后一行:

private字符串mPath=路径;

   if (mShouldRecord)            
       int mint = opus.startRecord(mPath);     <-- throws unsatisfiedLink - no implementation found   

startRecord在符号表中,但我不确定所有的函数parm类型是否匹配?请参阅"字符串2"。。。

startRecord__Ljava_lang_String_2)

===构建信息渐变和链接编辑===

link :
command: /usr/local/src/android-ndk-r10d/ndk-build NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=/home/rob/src/tmp/speechnw/libraries/opus/build/intermediates/ndk/release/Android.mk APP_PLATFORM=android-19 NDK_OUT=/home/rob/src/tmp/speechnw/libraries/opus/build/intermediates/ndk/release/obj NDK_LIBS_OUT=/home/rob/src/tmp/speechnw/libraries/opus/build/intermediates/ndk/release/lib APP_STL=stlport_static APP_ABI=armeabi-v7a
[armeabi-v7a] Compile thumb  : opus <= audio.c                       
...
[armeabi-v7a] SharedLibrary  : libopus.so
[armeabi-v7a] Install        : libopus.so => /home/rob/src/tmp/speechnw/libraries/opus/build/intermediates/ndk/release/lib/armeabi-v7a/libopus.so

build.gradle

defaultConfig{minSdk版本8targetSdkVersion 19版本代码1版本名称"1.1.1"

ndk {
    moduleName "opus"
    cFlags "-DANDROID_NDK " +
            "-DDISABLE_IMPORTGL " +
            "-w -std=gnu99 -O3 -fno-strict-aliasing -fprefetch-loop-arrays " +
            "-DNULL=0 -DSOCKLEN_T=socklen_t -DLOCALE_NOT_USED -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 "+
            "-Drestrict='' -D__EMX__ -DOPUS_BUILD -DFIXED_POINT -DUSE_ALLOCA -DHAVE_LRINT -DHAVE_LRINTF -fno-math-errno "
            "-DAVOID_TABLES "
    ldLibs "log", "m"
    stl "stlport_static"
    abiFilter "armeabi-v7a"
}

}

替换此行:

JNIEXPORT jint JNICALL Java_com_droidkit_opus_OpusLib_startRecord(JNIEnv *env, jclass class, jstring path) {

带有:

JNIEXPORT jint JNICALL Java_com_droidkit_opus_OpusLib_startRecord(JNIEnv *env, jobject javaThis, jstring path) {

您在C中定义的函数映射到Java中的静态方法,但在Java中您将其用作实例方法。我所替换的是:在C函数签名中用jobject javaThis,替换jclass class,。还请注意,在您的C头中,您还使用实例方法签名声明了函数,正如您想要的那样。