JNI: native im Interface

KrokoDiehl

Top Contributor
Hallo zusammen. Ich habe eine Frage im Zusammenhang mit JNI, aber zuvor etwas Rahmenwissen:

Ich deklariere ein Java-Interface mit native-Methoden, was auch soweit funktioniert:
Java:
package de.abs.comm;
public interface CoreInterface
{
    // ...
    public native void coreCreateShell();
}
Dieses Interface lasse ich von einer Klasse implementieren und anderswo werden zB diese nativen Methoden aufgerufen. Java-seitig kompiliert es und scheint kein Problem soweit zu geben.

Wenn ich die C-Bibliothek erstelle funktioniert auch soweit alles: Via
Code:
javah
lasse ich mir eine Headerdatei erstellen, die natürlich auf das Java-Interface verweist:
Code:
JNIEXPORT jboolean JNICALL Java_de_abs_comm_CoreInterface_coreCreateShell
  (JNIEnv *, jobject);
Gut, DLL wird erstellt, die Methode wird auch exportiert. Lade ich die Bibliothek doch via Java und versuche die Methode aufzurufen, kommt ein Unsatisfied Link Error:
Code:
java.lang.UnsatisfiedLinkError: libshelladapter.dll: Die angegebene Prozedur wurde nicht gefunden
(ich nehme an dass er mit "Prozedur" die
Code:
coreCreateShell()
meint).

Ich habe JNI schon erfolgreich verwendet, es liegt nun am Sonderfall, dass die native Methode in einem Interface deklariert wird, die "ausführende" Klasse aber eine andere Java-Klasse ist und in JNI-Nomenklatur
Code:
Java_de_abs_comm_CoreInterfaceImpl_coreCreateShell()
(<-- vgl. das "impl") heißen würde.

Nun die Frage: Geht dies überhaupt, bzw. muss man hier etwas "spezielles" beachten?
 
Ist auch implementiert.
Aber ich habe eben festgestellt, dass der Fehler noch im
Code:
System.loadLibrary("...")
-Aufruf von Java geworfen wird, d.h. er kommt noch nicht zum Aufruf der eigentlichen nativen Methode. Aber wer weiß, ob das nicht doch damit zutun haben könnte.
 
:lol: Das war gemein 😉

Zugegeben: Ich habe noch nie versucht, eine native Funtkion in einem Interface unterzubringen. Eigentlich würde ich ja sagen: Mach' eine Websuche! Aber wenn man nach "Java Native Interface interface" sucht, findet man erstmal nicht spontan die Information, ob man JNI-Methoden in einem interface definieren kann .... 🙄

Ein pragmatischer Test wäre, ein
Code:
class HelloWorldTest
{
    //... loadLibrary und main
    public static void main(String args)
    {
        HelloWorld h = new HelloWorld();
        h.sayIt();
    }
}
class HelloWorld
{
    public native void sayIt();
}
zu machen, die nativen Sachen dazu, und das dann auszuführen (das geht), und dann NUR die minimale Änderung zu machen
Code:
class HelloWorldTest
{
    //... loadLibrary und main
    public static void main(String args)
    {
        HelloWorld h = new HelloWorld[b]Impl[/b]();
        h.sayIt();
    }
}
[b]interface[/b] HelloWorld
{
    public native void sayIt();
}
[b]
class HelloWorldImpl
{
}
[/b]
und zu schauen, ob das dann noch funktioniert.
 
Ok, die Aufklärung des ganzen...

1) Man kann Methoden in einem Java-Interface nicht mit "native" deklarieren. Bei mir ist es eine abstrakte
Klasse mit native-Methoden. Das war mal wieder ein klassischer Fall, wo die Reihenfolge Denken-->Reden durcheinander gekommen ist 😳
2) Auch wenn abstrakte Klasse und implementierende Klasse in unterschiedlichen Packages liegen, bzw. anders heißen, funktioniert die Namensauflösung (also Java findet die nativen Implementierungen).
3) Das Problem bei mir war etwas anderes (was genau weiß ich leider nicht), aber ich habe es dadurch gelöst bekommen, dass ich alle DLLs und JARs komplett neu erstellt habe. Ich vermute dass irgendeine abhängige DLL nicht gepasst hat, so etwas hatte ich schon öfters, jedoch noch nie diese Fehlermeldung.

Sprich, mein Problem hat sich quasi erledigt. Danke für eure Zeit 😳
Ich schließe das Thema, sobald ich wirklich sicher bin, dass das mit den nativen Namen passt (...worum es in diesem Thema ja grundsätzlich geht).

*EDIT*
Ich kann es nun bestätigen: Man kann native Methoden in einer abstrakten Klasse deklarieren und sie von einer implementierenden Klasse benutzen lassen. Die Namen der C-Funktionen verweisen auf die abstrakte Klasse.
Mein Fehler hing tatsächlich mit abhängigen Bibliotheken zusammen.
 
Zuletzt bearbeitet:

Zurück
Oben