gpt4 book ai didi

android - 调用移植库的本地函数

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:39:47 24 4
gpt4 key购买 nike

我一直在关注本指南,了解如何使用 Android NDK 移植 LAME 库。 http://blog.libertadtech.com/2011/02/porting-lame-encoder-to-android-arm.html

一切正常,我得到了 libmp3lame.so 文件。

现在第一次测试我想调用简单的函数:

 void get_lame_version(char *strbuf, size_t buflen, const char *prefix);

我已经为 LAME 库编写了一个包装器:

package de.goddchen.android.youtubeconverter;

public class LameWrapper {

public static native void get_1lame_1version(char[] buf, int len,
char[] prefix);
}

我这样调用它:

public class MainActivity extends Activity {

static {
System.loadLibrary("mp3lame");
}

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
char[] buffer = new char[100];
LameWrapper.get_1lame_1version(buffer, 100, "".toCharArray());
((TextView) findViewById(R.id.text)).setText(buffer.toString());
}

}

但是我得到以下错误:

05-05 10:36:11.973: DEBUG/dalvikvm(199): Trying to load lib /data/data/de.goddchen.android.youtubeconverter/lib/libmp3lame.so 0x43757f78
05-05 10:36:12.053: DEBUG/dalvikvm(199): Added shared lib /data/data/de.goddchen.android.youtubeconverter/lib/libmp3lame.so 0x43757f78
05-05 10:36:12.123: DEBUG/dalvikvm(199): No JNI_OnLoad found in /data/data/de.goddchen.android.youtubeconverter/lib/libmp3lame.so 0x43757f78
05-05 10:36:12.573: DEBUG/dalvikvm(199): +++ not scanning '/system/lib/libwebcore.so' for 'get_1lame_1version' (wrong CL)
05-05 10:36:12.693: DEBUG/dalvikvm(199): +++ not scanning '/system/lib/libexif.so' for 'get_1lame_1version' (wrong CL)
05-05 10:36:12.693: DEBUG/dalvikvm(199): +++ not scanning '/system/lib/libFFTEm.so' for 'get_1lame_1version' (wrong CL)
05-05 10:36:12.703: DEBUG/dalvikvm(199): +++ not scanning '/system/lib/libmedia_jni.so' for 'get_1lame_1version' (wrong CL)
05-05 10:36:12.703: DEBUG/dalvikvm(199): +++ not scanning '/system/lib/libsrec_jni.so' for 'get_1lame_1version' (wrong CL)
05-05 10:36:12.703: WARN/dalvikvm(199): No implementation found for native Lde/goddchen/android/youtubeconverter/LameWrapper;.get_1lame_1version ([CI[C)V
05-05 10:36:12.703: DEBUG/AndroidRuntime(199): Shutting down VM
05-05 10:36:12.753: INFO/ActivityManager(52): Start proc com.android.alarmclock for broadcast com.android.alarmclock/.AlarmInitReceiver: pid=213 uid=10017 gids={}
05-05 10:36:12.773: WARN/dalvikvm(199): threadid=3: thread exiting with uncaught exception (group=0x4001aa28)
05-05 10:36:12.783: ERROR/AndroidRuntime(199): Uncaught handler: thread main exiting due to uncaught exception
05-05 10:36:12.883: ERROR/AndroidRuntime(199): java.lang.UnsatisfiedLinkError: get_1lame_1version
05-05 10:36:12.883: ERROR/AndroidRuntime(199): at de.goddchen.android.youtubeconverter.LameWrapper.get_1lame_1version(Native Method)
05-05 10:36:12.883: ERROR/AndroidRuntime(199): at de.goddchen.android.youtubeconverter.MainActivity.onCreate(MainActivity.java:19)
05-05 10:36:12.883: ERROR/AndroidRuntime(199): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
05-05 10:36:12.883: ERROR/AndroidRuntime(199): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)
05-05 10:36:12.883: ERROR/AndroidRuntime(199): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2417)
05-05 10:36:12.883: ERROR/AndroidRuntime(199): at android.app.ActivityThread.access$2100(ActivityThread.java:116)
05-05 10:36:12.883: ERROR/AndroidRuntime(199): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1794)
05-05 10:36:12.883: ERROR/AndroidRuntime(199): at android.os.Handler.dispatchMessage(Handler.java:99)
05-05 10:36:12.883: ERROR/AndroidRuntime(199): at android.os.Looper.loop(Looper.java:123)
05-05 10:36:12.883: ERROR/AndroidRuntime(199): at android.app.ActivityThread.main(ActivityThread.java:4203)
05-05 10:36:12.883: ERROR/AndroidRuntime(199): at java.lang.reflect.Method.invokeNative(Native Method)
05-05 10:36:12.883: ERROR/AndroidRuntime(199): at java.lang.reflect.Method.invoke(Method.java:521)
05-05 10:36:12.883: ERROR/AndroidRuntime(199): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
05-05 10:36:12.883: ERROR/AndroidRuntime(199): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
05-05 10:36:12.883: ERROR/AndroidRuntime(199): at dalvik.system.NativeStart.main(Native Method)

谁能告诉我调用 libmp3lame.so 函数的正确方法?

最佳答案

遗憾的是,您不能只从 Java 调用任何旧的 C 函数。您必须使用具有“损坏”名称的函数或使用 JNI_OnLoad 机制。无论哪种方式,Dalvik VM 都会向函数调用添加额外的参数,这是常规的蹩脚 get_version_number 函数所不期望的。

example of using JNI解释名称修饰。对于您的 Java 类,您需要具有具有此原型(prototype)的函数:

void Java_de_goddchen_android_youtubeconverter_LameWrapper_get_11lame_11version
(JNIEnv *, jclass, jcharArray, jint, jcharArray);

JNIEnv 和 jclass 参数是调用接口(interface)的一部分。如果您使用的是 C++,请记住指定 extern "C"。 javah 工具将为您生成正确的头文件。

如果我这样做,我可能会为我需要的蹩脚调用编写 JNI C 包装器函数。在这种特殊情况下,我没有使用带有长度参数的 char * 并将空的 char * 作为最后一个参数传递,而是创建了一个更简单的 Java 到 C 接口(interface)刚刚返回了一个 Java String。所以在 Java 中:

package de.goddchen.android.youtubeconverter;

public class LameWrapper {
public static native String getVersion();
}

然后在 C 中,调用实际的蹩脚 API:

JNIEXPORT jstring JNICALL Java_de_goddchen_android_youtubeconverter_LameWrapper_getVersion
(JNIEnv * env, jclass c)
{
char buffer[80];
get_lame_version(buffer, sizeof(buffer) - 1, "");
return (*env)->NewStringUTF(env, buffer));
}

然后在 Java/Dalvik 端控制这里创建的新 String 的生命周期。

关于android - 调用移植库的本地函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5896464/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com