2010-10-27 5 views
19

Mam działającą implementację biblioteki NDK i odpowiadającej jej klasy Java. Ale nie jestem w stanie dodać przeciążonej metody do tej klasy. Obecnie moja klasa zawiera:Jaki jest poprawny sposób pisania podpisów metody natywnej w Android NDK?

package com.package; 

public class MyClass 
{ 
    public static native String getFileName(); 
    static 
    { 
    System.loadLibrary("mylib"); 
    } 
} 

Mój plik jniwrappers.cpp ma następującą deklarację:

grzywny
JNIEXPORT jstring JNICALL 
Java_com_package_MyClass_getFileName(_JNIEnv* env, jobject thiz); 

do tej pory wszystko działa. Ale obok zmodyfikować moją klasę:

package com.package; 

public class MyClass 
{ 
    public static native String getFileName(); 
    public static native String getFileName(int index); 
    ... 
} 

i dodać do jniwrappers.cpp kolejną deklarację:

JNIEXPORT jstring JNICALL 
Java_com_package_MyClass_getFileName__I(_JNIEnv* env, jobject thiz, jint index); 

To kompiluje grzywny, Android uruchomieniu aplikacji nie dostać UnsatisfiedLinkError ale gdy wywołuje drugą metodę z argument, że pierwsza funkcja C++ jest wywoływana, ale nie druga. Mam inne metody z argumentami w tej klasie, ale żadna z nich nie jest przeciążona, więc ich odpowiednie podpisy JNI nie zawierają argumentów.

Co więc robię źle?

Odpowiedz

20

Musisz dodać __ na końcu oryginalnej funkcji getFileName, gdy jest ona przeciążona. Twoje 2 C prototypy funkcji powinna teraz wyglądać następująco:

JNIEXPORT jstring JNICALL Java_com_package_MyClass_getFileName__ 
    (JNIEnv *, jclass); 

JNIEXPORT jstring JNICALL Java_com_package_MyClass_getFileName__I 
    (JNIEnv *, jclass, jint); 
+0

To była pierwsza rzecz, którą próbowałem, ale coś poszło nie tak i mam UnsatisfiedLinkError. Teraz ponowiłem próbę i wszystko działało. Wielkie dzięki! –

25

Należy użyć javah narzędzie do generowania tych podpisów.

Aby z niego skorzystać, należy utworzyć plik klasy, w którym jest dostępna funkcja native. Otrzymasz plik class.

Uruchom javah -jni com.organisation.class_with_native_func, wygeneruje plik nagłówka dla Ciebie.

To znacznie czystsze niż samodzielna edycja.

+3

Dzięki, właśnie tego powinienem użyć. Ale nadal wiedząc, internals jest bardzo przydatny. –

+0

Lub po prostu użyj przełącznika wiersza poleceń -classpath, aby skierować javah do katalogu, w którym skompilowano plik klasy (np. 'Javah -classpath/path/to/jar -jni com.package.name.YourClass'). –

Powiązane problemy