使用本机lib(仅限C,没有C++),并且找不到实现
Using native lib (C only, no C++), and No Implementation Found
尝试在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头中,您还使用实例方法签名声明了函数,正如您想要的那样。
相关文章:
- 如果没有malloc,链表实现将失败
- 如何在c++中实现处理器调度模拟器
- 如何在c++中使用引用实现类似python的行为
- 实现无开销push_back的最佳方法是什么
- 使用简单类型列表实现的指数编译时间.为什么
- 如何在BST的这个简单递归实现中消除警告
- 实现一个在集合上迭代的模板函数
- 我应该实现右值推送功能吗?我应该使用std::move吗
- 如何正确实现和访问运算符的各种自定义枚举器
- C++Union/Struct位域的实现和可移植性
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 在c++中实现LinkedList时,应出现未处理的错误
- 为左值和右值的包装器实现C++范围
- 使用模板进行堆栈实现; "name followed by :: must be a class or namespace"
- 使用GSoap实现ONVIF
- 在用于格式4的arm模拟器中实现功能时的一个问题
- 用于AVX的ln(x)的实现,m256
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 在C++中,如何在类和函数(可能是模板化的)的头中编写完整的实现
- std::random_device是如何实现的