2013-07-14 3 views
0

Я работаю над настройкой NDK для моего проекта Android. У меня есть проект андроида с текстовым представлением, который выводит на эмулятор «Output =» У меня есть собственная функция под названием somefunc(), которую я добавляю к этой строке, и она выдает сообщение об ошибке.Android NDK и родной метод JNI не найден

E/AndroidRuntime(2242): java.lang.UnsatisfiedLinkError: Native method not found: com.ndktest.MainActivity.somefunc:()I 

У меня есть три файлы, которые я считаю необходимы. MainActivity.java, test.c, и Android.mk.

В test.c Я имею

#include <string.h> 
#include <jni.h> 

JNIEXPORT int JNICALL 
Java_com_ndktest_MainActivity_somefunc(JNIEnv * env, jobject obj) 
{ 
return 2; 
} 

И Android.mk

LOCAL_PATH := $(call my-dir) 
include $(CLEAR_VARS) 
LOCAL_MODULE := test 
LOCAL_SRC_FILE := test.c 
include $(BUILD_SHARED_LIBRARY) 

И MainActivity.java

package com.ndktest; 

import com.ndktest.R; 

import android.os.Bundle; 
import android.app.Activity; 
import android.util.Log; 
import android.widget.TextView; 

public class MainActivity extends Activity { 

static 
{ 
    System.loadLibrary("test"); 
} 
public native int somefunc(); 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    TextView tv = new TextView(getBaseContext()); 
    tv.setTextSize(30); 
    String s = "Ouput="+somefunc(); 
    tv.setText(s); 
    this.setContentView(tv); 
} 
} 

Я понимаю из различных руководств онлайн, что орфографические ошибки являются наиболее распространенной причиной этой ошибки. Я попытался изо всех сил проверить наличие орфографической ошибки в пакете и в коде функции c, и до сих пор я этого не вижу. Я также могу запустить «ndk-build» в make-файле, и он компилируется без ошибок. Он создает libtest и загружает библиотеку. Я попробовал попытку поймать его, и попытка проходит для библиотеки загрузки системы. Поэтому я предполагаю, что есть орфографическая ошибка или ошибка в том, как я назвал функцию c. Я прочитал, что c-функцию следует вызывать в Java_ [пакет с символами подчеркивания вместо точек] [java class] [имя функции]. Я думаю, что соблюдаю это. Я извиняюсь, что первая половина вопроса выглядит как стереотипный вопрос «решить это для меня». Мне просто нужен код, чтобы он показывал, что называется пакетами и как выглядит make. Спасибо

+0

В лог-кадре должны быть сообщения о попытке загрузки библиотеки - вы можете игнорировать предупреждение о jnionload, но вы должны увидеть указание на успех или неудачу там. Технически ваш тип возврата должен быть jint not int, но на практике они могут быть одинаковыми.Иногда, если вы действительно застряли, начиная с образца hello-jni и превращая его в свои потребности, одно изменение в промежутке между тестами может быть полезно при определении того, где вы поступили неправильно. –

+0

Спасибо за ответ, hello-jni отлично работает, я чувствую, что должно быть что-то не так с тем, как я создал свой проект. Я попробую сделать новый проект и посмотреть, работает ли это. – user700508

+0

Это не твоя проблема, но я сражался несколько часов с подобной проблемой. Моя проблема заключалась в том, что мои собственные функции содержали символы подчеркивания (например, «native int get_result()»). Все было в порядке имен jni (Java_mypackage_myclass_get_result ...), но JNI не обнаружил, что «get_result» - это имя функции, поэтому я получаю UnsatisfiedLinkerror. Решение заключалось в том, чтобы удалить все подчеркивания из функций (например, преобразовать get_result() в getResult()). (я использовал «javah -jni» для создания файлов заголовков, и у меня не было никаких предупреждений) Надеюсь, что это поможет кому-то – Miquel

ответ

2

Вы можете получить правильные прототипы для своих родных функций по телефону

javah -classpath bin/classes -d jni com.ndktest.MainActivity

из исходного каталога. Это создаст заголовок com_ndktest_MainActivity.h, который может быть включен в ваш файл C.

(КСТАТИ: если ваш родной файл компилируется в C++ вы должны extern "C" {...})

+2

Эта проблема также может возникнуть, если ваш вызов «System.loadLibrary» отсутствует или класс, который не используется. – Oren

0

Вы можете попробовать изменить из

JNIEXPORT INT JNICALL

в

JNIEXPORT jint JNICALL

Смежные вопросы