use*_*736 6 java-native-interface android header-files unsatisfiedlinkerror
我是jni的新手,我正在修改一个教程来实现一个简单的本机方法,但是我得到了一个不满意的链接错误.据我所知,我完全按照教程中的步骤进行操作.请帮我.
这是java包装器代码:
package com.cookbook.jni;
public class SquaredWrapper {
// Declare native method (and make it public to expose it directly)
public static native int squared(int base);
// Provide additional functionality, that "extends" the native method
public static int to4(int base)
{
int sq = squared(base);
return squared(sq);
}
// Load library
static {
System.loadLibrary("squared");
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的Android.mk文件的样子:
LOCAL_PATH:= $(调用my-dir)
包括$(CLEAR_VARS)
LOCAL_MODULE:=平方LOCAL_SRC_FILES:= squared.c
包含$(BUILD_SHARED_LIBRARY)
这是我的.c文件的样子:
#include "squared.h"
#include <jni.h>
JNIEXPORT jint JNICALL Java_org_edwards_1research_demo_jni_SquaredWrapper_squared
(JNIEnv * je, jclass jc, jint base)
{
return (base*base);
}
Run Code Online (Sandbox Code Playgroud)
这是我的.h文件的样子:
enter code here/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_cookbook_jni_SquaredWrapper */
#ifndef _Included_com_cookbook_jni_SquaredWrapper
#define _Included_com_cookbook_jni_SquaredWrapper
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_cookbook_jni_SquaredWrapper
* Method: squared
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_com_cookbook_jni_SquaredWrapper_squared
(JNIEnv *, jclass, jint);
#ifdef __cplusplus
}
#endif
#endif
Run Code Online (Sandbox Code Playgroud)
您的JNI签名不匹配.在.c文件中,更改:
JNIEXPORT jint JNICALL Java_org_edwards_1research_demo_jni_SquaredWrapper_squared
Run Code Online (Sandbox Code Playgroud)
至
JNIEXPORT jint JNICALL Java_com_cookbook_jni_SquaredWrapper_squared
Run Code Online (Sandbox Code Playgroud)
通常,有两种方法可以将本机C通过JNI"粘合"到Java函数中.第一个是您在这里尝试做的事情,即使用JNI将识别并与您的相应Java代码相关联的预定签名.第二种是在包含库时将函数指针,签名和Java类名称传递给JNI.
这是将本机函数绑定到适当的Java代码的第二种方法(这将是您的.c文件):
#include "squared.h"
#include <jni.h>
static const char* SquaredWrapper = "com/cookbook/jni/SquaredWrapper";
jint squared(JNIEnv * env, jobject this, jint base) {
return (base*base);
}
// Methods to register for SquaredWrapper
static JNINativeMethod SquareWrapperMethods[] = {
{"squared", "(I)I", squared}
};
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* env;
if ( (*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_6) != JNI_OK)
return JNI_ERR;
jclass class = (*env)->FindClass(env, SquaredWrapper);
(*env)->RegisterNatives(env, class, SquaredWrapperMethods, sizeof(SquaredWrapperMethods)/sizeof(SquaredWrapperMethods[0]));
return JNI_VERSION_1_6;
}
void JNI_OnUnload(JavaVM* vm, void* reserved) {
JNIEnv* env;
if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_6) != JNI_OK)
return;
jclass class = (*env)->FindClass(env, SquaredWrapper);
(*env)->UnregisterNatives(env, class);
return;
}
Run Code Online (Sandbox Code Playgroud)
这是一个很长的时间,但它在绑定本机代码时为您提供了更多的灵活性.平方和包含的定义如您所料.在第4行,static const char*SquaredWrapper是一个转义字符串,其中包含要绑定平方的类的完全限定包名.接近底部的是JNI_OnLoad和JNI_OnUnLoad函数,它们负责绑定和解除库加载和卸载时的函数绑定.最后一块是JNINativeMethod数组.此数组包含每个条目的大小为3的数组,其组件是作为const char*的方法的Java名称,Java方法的JNI签名以及绑定到该方法的本机C函数指针.JNI函数签名告诉环境参数列表格式和Java函数的返回值.格式为"(Arg1Arg2Arg3 ...)Ret",所以一个接受int和double并返回一个float的函数将具有"(ID)F"的签名,并且一个不带参数并返回void的函数将是"()V".我用这个方便的备忘单来记住大部分的简写:
http://dev.kanngard.net/Permalinks/ID_20050509144235.html
祝好运 :)
编辑:哦,顺便说一下,您可能希望将JNI_OnLoad和JNI_UnOnLoad的签名添加到标头中,并更改本机函数原型的名称以反映新的.c文件.
| 归档时间: |
|
| 查看次数: |
7491 次 |
| 最近记录: |