2010-07-30 1 views
5

Ich definiere eine Java-Klasse von C mit dem JNI Aufruf DefineClass() und dann registriere ich die native Rückrufe für die Methoden in der Klasse einheimisch. Die Klasse hat zwei statische Methoden, die beide nativ sind. Ich verwende RegisterNatives(), um die nativen Funktionen zu registrieren. Beide Anrufe sind erfolgreich.Ich definiere eine Java-Klasse von C mit DefineClass(), aber bekomme UnzufriedeneLinkError

Aber wenn ich diese native Methoden von meinem Java-Code verweisen bekomme ich java.lang.UnsatisfiedLinkError myPackage.myClass.myMethod (I) V

Aber ich weiß, dass defineClass ein Klassenobjekt für MyPackage.MyClass zurückgekehrt und ich wissen, dass myMethod (I) V wurde als eine Methode für diese Klasse registriert.

Ich bekomme diesen Fehler, gerade wie es ist, main() auszuführen - wo der Aufruf an meine native Methode ist (vorläufig, zum Testen).

Als Test versuchte ich DefineClass zweimal auf dem gleichen JNIEnv, um zu sehen, was passiert ist. Ich erhalte einen doppelten Klassendefinitionsfehler. Ich habe auch versucht, FindClass() aufzurufen, nachdem ich es definiert habe, und der JNIEnv gibt einen Verweis auf die definierte Klasse zurück.

Also definiere ich definitiv die Klasse dynamisch, aber es schlägt fehl, wenn ich versuche, auf seine Methoden zu verweisen.

Irgendwelche Ideen? Alle Eingaben geschätzt.

Plattform: Windows, 32-Bit-Code auf 64-Bit-XP.

+0

Könnten Sie eine ältere Version Ihrer DLL irgendwo in Ihrem Pfad haben? –

+0

Wenn Sie Ihre DLL kompiliert haben, haben Sie die Funktionen exportiert? –

+0

Romain: Meine Funktionen müssen nicht exportiert werden und die DLL-Version ist irrelevant - die DLL, die die Funktionen mit RegisterNatives() registriert, ist die DLL, die die Funktionen bereitstellt. Die Funktionen sind definitionsgemäß verfügbar, wenn RegisterNatives() aufgerufen wird. –

Antwort

2

Scheint, dass Sie eine native Methode nicht definieren können, die DefineClass() verwendet, und rufen Sie die systemeigene Methode direkt von Ihrem injizierten Code auf. Sie müssen eine Trampolin-Methode in Ihrer injizierten Klasse (in Form von Java-Byte-Codes) haben, die dann Ihre nativen Methoden aufruft. Nur dann wird es funktionieren. Ich habe drei Tage gebraucht, um das auszuarbeiten.

Ein weiteres Problem ist, dass der eingegebene Code gültig ist. Der Code, den ich versuchte, sah gültig aus, aber bei näherer Betrachtung zog ich eine 4 Byte große Konstante aus dem Konstanten-Pool als Operand für einen 8-Byte-Befehl. Damit ist der Verifier gescheitert. Sobald das repariert wurde (und das native Trampolin), hat alles funktioniert.

Aber um dort durch die verschiedenen Permutationen zu gelangen, die ich versuchen musste, dauerte 3 Tage. Fühlte mich gut, wenn ich arbeitete.

Wie macht man das Trampolin? Sehen Sie sich die Beispiele (in C) an, die mit dem Java SDK ausgeliefert werden. Sie sind ziemlich lang und nicht zum Posten geeignet.

Verwandte Themen