Interfaceübergabe in JNI

Status
Nicht offen für weitere Antworten.

deathlock

Aktives Mitglied
Hi Leute!

Noch mal eine Frage zu JNI:
Ist es möglich über JNI Interfaces zu übergeben bzw. zu retournieren (in beide Richtungen Java <-> C++)?

zB wie unter Java:
public IMyInterface myMethod (int i, IAnotherInterface);

Danke schonmal für alle Kommentare/Antworten.

LG,
deathlock.
 

thE_29

Top Contributor
Also von C++ zurück gehts nicht, weil was tut Java mit einem C++ Interface?!

Java Code:

JNITest2.java:
Code:
public class JNITest2 implements IJNI
{
public void test()
{
System.out.println("Im Test!");
}

public void test2(int testvalue)
{
System.out.println("Im Test2: " + testvalue);

}

public void test3(IJNI interf)
{
System.out.println("Interface ist class: " + interf.getClass());

}

public native void Test(IJNI interf);

public JNITest2()
{
	Test(this);
}


public static void main(String args[])
{
new JNITest2();
}

static {
System.loadLibrary("JNITest2");
}
}

IJNI.java:
Code:
public interface IJNI
{
public void test();
public void test2(int atestvalue);
public void test3(IJNI interf);
}


C Code:

main.cpp
Code:
#include "JNITest2.h"
#include <stdio.h>


JNIEXPORT void JNICALL Java_JNITest2_Test
  (JNIEnv * env , jobject obj , jobject interfac)

{

	jclass icls = env->GetObjectClass(interfac);
	
	jmethodID jmid = env->GetMethodID(icls, "test", "()V");

	if(jmid == 0)
		printf("Konnte void test() nicht laden!");
	else
		env->CallVoidMethod(interfac, jmid); 

	jmid = env->GetMethodID(icls, "test2", "(I)V");

	if(jmid == 0)
		printf("Konnte void test2(int a) nicht laden!");
	else
		env->CallVoidMethod(interfac, jmid, (int)29); 

	jmid = env->GetMethodID(icls, "test3","(LIJNI;)V");


	if(jmid == 0)
		printf("Konnte void test3(IJNI interfac) nicht laden!");
	else
		env->CallVoidMethod(interfac, jmid, interfac); 

}

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

#ifndef _Included_JNITest2
#define _Included_JNITest2
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     JNITest2
 * Method:    Test
 * Signature: (LIJNI;)V
 */
JNIEXPORT void JNICALL Java_JNITest2_Test
  (JNIEnv *, jobject, jobject);

#ifdef __cplusplus
}
#endif
#endif


Ausgabe hat gesagt.:
C:\tmp\java-forum\jni\JNITest2>java JNITest2
Im Test!
Im Test2: 29
Interface ist class: class JNITest2
 

deathlock

Aktives Mitglied
Hi!

Cool. Danke!
Ja stimmt C++ Interface kann nicht funktionieren. Wie sieht es aber mit einem COM Interface aus. Darauf müsste man doch in Java (als Return-Wert) zugreifen können, oder?

lg.
 

thE_29

Top Contributor
Was isn ein COM Interface?!

Das Problem ist, das Java net direkt auf C Typen/Klassen zugreifen kann, weil die Typen halt anders sind!
 

deathlock

Aktives Mitglied
Ist dir COM (Component Object Model) ein Begriff?

Musste ich auch feststellen. Ist es richtig, dass man bei C++ Klassen, die man über JNI zu Java Klassen macht, in Java keine Methoden Aufrufen kann, sondern nur Zugang zu den Attributen hat?
 

thE_29

Top Contributor
Wie kann man C++ Klassen zu Java Klassen machen?!


Sagen tut mir COM schon was, nur beschäftigt habe ich mich damit noch nicht wirklich...
 

thE_29

Top Contributor
Welches Bsp?

Und welche Attribute?!

Du kannst von Java aus C Methoden aufrufen (die die native sind) und von C aus Java Methoden?!

Was brauchst du bitte den noch?!
 

deathlock

Aktives Mitglied
Naja, ich dachte nur daran aus einer C++ Klasse eine Java Klasse zu basteln. Etwas ähnliches wird beim oben verlinkten Tutorial im Listing 5 gemacht. Ist aber nicht weiter wichtig.

Andere Frage: Welche Gründe kann es haben, dass
env->FindClass("Classname");
NULL zurückliefert, obwohl es diese Klasse gibt?
Sprich: was können Gründe sein, warum er sie nicht findet?
 

thE_29

Top Contributor
Schreibst du sie richtig rein??

Da gehört net nur Klassenname, das gehört immer irgendwie..

http://forum.java.sun.com/thread.jspa?threadID=747369

Noch ein findclass Bsp.: http://www.inonit.com/cygwin/jni/invocationApi/launch.html

Desweiteren ist das Oberschwachsinn² Java Dinge via Java Methoden in JNI zu ändern?!

Machs doch gleich in Java und übergib das richtige dem C Objekt..

Sowas HIRNLOSES habe ich selten gesehen..

Geschwindigkeitsvorteil wirds sowieso keinen haben, weil du zig Methoden brauchst, bist mal an die Felder etc kommst...


Es ist zwar net zum Spielen, aber das wars auch schon...

Java Dinger sollte Java machen und alles andere was net geht, soll C machen..

Aber wozu sollte C Java Sachen machen?!

Außer das es schwieriger ist und Fehleranfälliger sehe ich da keinen Sinn dahinter...
 

mischer

Aktives Mitglied
Hast du den kompletten Namen gegeben und ihn richtig formatiert?

Die Formatierung ist "L + <kompletten Packagename, getrennt durch /> + <Klassenname> + ;".

Also z.B.:
Code:
env->FindClass("LmeinPackage/meinUnterPackage/MeineKlasse;");

mfg
mischer

[EDIT] Wieder einer schneller :roll: [/EDIT]
 

deathlock

Aktives Mitglied
Danke. Hab den Packagenamen vergessen.

Stimmt schon es hat keinen Sinn. Aber ich schreibe gerade eine Test Applikation um dem Projektmanager zu zeigen wie das Ganze funktioniert, bzw. wie man mit JNI Interaktion zw. C++ und Java betreibt. Es soll später natürlich nicht mehr so genutzt werden.
 

thE_29

Top Contributor
Jo, zum Spielen isses net ;)

WIe gesagt, nur Sinn hat es net wirklich... :)

Außer man braucht 1mal nen Wert und macht dann zig millionen Rechenintensiven Interaktionen (da sollte ja C schneller als java)
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Oben