调用移植库的原生功能 [英] Invoking native functions of ported library

查看:132
本文介绍了调用移植库的原生功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在关注如何端口LAME库和Android NDK对本指南。 HTTP://blog.libertadtech .COM / 2011/02 /移植瘸-CN codeR-到Android的arm.html

i have been following this guide on how to port the LAME library with and Android NDK. http://blog.libertadtech.com/2011/02/porting-lame-encoder-to-android-arm.html

每一个运行良好的我得到了libmp3lame.so文件。

Every worked fine an i got the libmp3lame.so file.

现在的第一个测试我想叫简单的函数:

Now for a first test i wanted to call the simple function:

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

我已经写了包装的LAME库:

I have written a wrapper for the LAME library:

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());
    }

}

但我得到以下错误:

But i get the following error:

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的功能?

Can someone please point me to the right way to call the functions of libmp3lame.so?

推荐答案

不幸的是,你不能仅仅从Java调用任何旧的C函数。你必须使用一个功能一个错位名称或使用JNI_OnLoad机制。无论哪种方式,Dalvik虚拟机将增加额外的参数给函数调用,经常跛脚 get_version_number 功能不期待的。

Sadly you can't just call any old C function from Java. You have to use a function with a "mangled" name or use the JNI_OnLoad mechanism. Either way, the Dalvik VM will add extra arguments to the function call that the regular lame get_version_number function is not expecting.

使用JNI 解释了名字改编的这例子。为了您的Java类,你需要有这个原型的函数:

This example of using JNI explains the name mangling. For your Java class, you would need to have a function with this prototype:

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

JNIEnv的和JCLASS参数是调用接口的一部分。请记住要指定的externC如果你使用的是C ++。该javah工具将产生正确的头文件给你。

The JNIEnv and jclass arguments are part of the calling interface. Remember to specify extern "C" if you're using C++. The javah tool will produce the right header file for you.

如果我是这样做的,我可能会写JNI C包装功能的瘸腿呼叫我需要的。在这种特殊情况下,而不是使用的char * 带长度参数,并传递一个空的char * 作为最后一个的说法,我想创建一个简单的Java到C接口,刚回到一个Java 字符串。因此,在Java的:

If I were doing this, I'd probably write JNI C wrapper functions for the lame calls I needed. In this particular case instead of using a char * with a length argument, and passing an empty char * as the last argument, I'd create a simpler Java to C interface that just returned a Java String. So in Java:

package de.goddchen.android.youtubeconverter;

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

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

Then in C, which calls the actual lame 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的一面。

The life cycle of the new String created here is then controlled on the Java/Dalvik side.

这篇关于调用移植库的原生功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆