Android在共享库中调用函数

时间:2014-07-03 13:20:01

标签: android android-ndk java-native-interface

我正在尝试按照本教程 http://www3.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html 但是我在eclipse中制作了一个Android应用程序

所以我创建了空白项目并添加了一个新类

package com.example.jpgtest;

import android.util.Log;

public class TestJNIPrimitive {
    //static {
          //System.loadLibrary("myjni"); // myjni.dll (Windows) or libmyjni.so (Unixes)
     //     System.load("d:/libjpeg.so");
     //     Log.d("TestJNIPrimitive", "load ok");
     //  }

       // Declare a native method average() that receives two ints and return a double containing the average
       private native double average(int n1, int n2);

       // Test Driver
       public static void main() {
           System.load("d:/libjpeg.so");
           Log.d("TestJNIPrimitive", "load ok");

          double d =  new TestJNIPrimitive().average(3, 2);

          //double d =  new TestJNIPrimitive().average(3, 2);
          Log.d("TestJNIPrimitive", "d="+d);
       }
}

并从onCreate()

调用它
TestJNIPrimitive t = new TestJNIPrimitive();
        t.main();

我像这样制作了c和h文件 TestJNIPrimitive.h /

* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class TestJNIPrimitive */

#ifndef _Included_TestJNIPrimitive
#define _Included_TestJNIPrimitive
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     TestJNIPrimitive
 * Method:    average
 * Signature: (II)D
 */
JNIEXPORT jdouble JNICALL Java_TestJNIPrimitive_average
  (JNIEnv *, jobject, jint, jint);

#ifdef __cplusplus
}
#endif
#endif

TestJNIPrimitive.c

#include <jni.h>
#include "TestJNIPrimitive.h"

JNIEXPORT jdouble JNICALL Java_TestJNIPrimitive_average(JNIEnv *env, jobject thisObj, jint n1, jint n2) 
{
   jdouble result;
   //printf("In C, the numbers are %d and %d\n", n1, n2);
   result = ((jdouble)n1 + n2) / 2.0;
   // jint is mapped to int, jdouble is mapped to double
   return result;
}

我构建它并在我的驱动器根目录上创建一个libjpg.so 我检查符号

$ readelf -Ws /cygdrive/d/libjpeg.so | grep average
   272: 00003f5c    72 FUNC    GLOBAL DEFAULT    7 Java_TestJNIPrimitive_average
  1896: 00003f5c    72 FUNC    GLOBAL DEFAULT    7 Java_TestJNIPrimitive_average

当我运行它时,负载正常,但平均调用失败 找不到本机Lcom / example / jpegtest / TestJNIPrimative; .average(II)D

的实现

请问任何想法,我真的坚持这个

由于

2 个答案:

答案 0 :(得分:3)

你错过了进入JNI的包装。这就是找不到该功能的原因。

您的Java包是:com.example.jpgtest

所以你的Native函数必须是:

JNIEXPORT jdouble JNICALL Java_com_example_jpgtest_TestJNIPrimitive_average(JNIEnv *env, jobject thisObj, jint n1, jint n2) 
{
   ...
}

使用ndk-build编译后,使用新的libjpeg.so必须正常工作。

我必须补充一点,你的java看起来很奇怪(对我来说不太重要)。我将把它实现为:

package com.example.jpgtest;

import android.util.Log;

public class TestJNIPrimitive 
{
    // Test Driver
    public static void main()
    {
          Log.d("TestJNIPrimitive", "load ok");

          double d =  new TestJNIPrimitive().average(3, 2);
          Log.d("TestJNIPrimitive", "d="+d);
    }
    // Native functions (Callbacks from Java to C++)
    // =========================================================================
    // Declare a native method average() that receives two ints and return a double containing the average
       private native double average(int n1, int n2);

    // Load Native Libraries
    // =========================================================================
    static 
    {
         System.load("libjpeg.so");
    }
}

所以必须在文件夹libs / armeabi-v7a

我想要一个基本的理论检查thisspecifications

答案 1 :(得分:0)

我无法弄清楚问题,但我读了这个 https://developer.android.com/tools/sdk/ndk/index.html

我构建并运行hello-jni示例,然后我构建一个新项目,然后在测试的jni文件夹中添加并更改包名称和类名以匹配新项目

然后我开始根据我的需要修改功能,现在可以

不容易这个