View Full Version : [C#, Java] - Richiamare Java da C#
Ho la necessita' di richiamare una funzione (tante in realta') scritta in Java da parte di un mio programma C#
Dispongo dei sorgenti di entrambi, ma non e' mia facolta' ne volonta' cambiare il codice Java monolitico e immenso che mi si para davanti.
Inoltre ho la necessita' di una discreta velocita', nel senso che dovro' richiamare le funzioni Java per tante volte. Sono decisamente veloci, quindi mi seccherebbe dover spendere piu' tempo per i passaggi di informazioni piuttosto che per i calcoli veri e propri, dato che il flusso e' gia' su un percorso critico.
Idee possibili?
!k-0t1c!
13-06-2009, 16:09
JNI/COM. In ogni caso sappi che non sarà una bella esperienza. Se l'input e l'output non sono particolarmente strutturati (e quindi la (de)serialization non costa troppo) puoi considerare l'uso di socket o ancora meglio named pipes, ma quello richiederebbe una serie di stub in java wrappati in una classe per gestire i messaggi...Visto che non credo che la questione sia per un progettino scolastico ti sconsiglio invece di guardare IKVM et similia.
^TiGeRShArK^
13-06-2009, 16:25
Ho la necessita' di richiamare una funzione (tante in realta') scritta in Java da parte di un mio programma C#
Dispongo dei sorgenti di entrambi, ma non e' mia facolta' ne volonta' cambiare il codice Java monolitico e immenso che mi si para davanti.
Inoltre ho la necessita' di una discreta velocita', nel senso che dovro' richiamare le funzioni Java per tante volte. Sono decisamente veloci, quindi mi seccherebbe dover spendere piu' tempo per i passaggi di informazioni piuttosto che per i calcoli veri e propri, dato che il flusso e' gia' su un percorso critico.
Idee possibili?
hai già provato ad usare il j# redistributable?
Io l'ho utilizzato per delle funzioni delle JFC, ma ora sinceramente mi sfugge se si può usare anche per altre funzioni....:stordita:
cmq lo puoi scaricare da qui:
http://www.microsoft.com/DOWNLOADS/details.aspx?familyid=F72C74B3-ED0E-4AF8-AE63-2F0E42501BE1&displaylang=en
se gli vuoi dare un'occhiata...
!k-0t1c!
13-06-2009, 16:42
hai già provato ad usare il j# redistributable?
Io l'ho utilizzato per delle funzioni delle JFC, ma ora sinceramente mi sfugge se si può usare anche per altre funzioni....:stordita:
cmq lo puoi scaricare da qui:
http://www.microsoft.com/DOWNLOADS/details.aspx?familyid=F72C74B3-ED0E-4AF8-AE63-2F0E42501BE1&displaylang=en
se gli vuoi dare un'occhiata...
Manca tutta la compatibilità...Il problema di gugoXX non mi pare quello di scrivere codice per .NET con sintassi Java ma di controllare codice Java da C#. In un contesto aziendale dove ci fossero fondi sufficienti a disposizione potrebbe valutare l'uso di http://www.jnbridge.com/jnbpro.htm ma non credo proprio possa pensare di portare il codice Java su cui non ha il controllo su .NET, a prescindere dalla compatibilità sintattica o delle librerie di base.
^TiGeRShArK^
13-06-2009, 17:41
Manca tutta la compatibilità...Il problema di gugoXX non mi pare quello di scrivere codice per .NET con sintassi Java ma di controllare codice Java da C#. In un contesto aziendale dove ci fossero fondi sufficienti a disposizione potrebbe valutare l'uso di http://www.jnbridge.com/jnbpro.htm ma non credo proprio possa pensare di portare il codice Java su cui non ha il controllo su .NET, a prescindere dalla compatibilità sintattica o delle librerie di base.
:mbe:
se il suo codice java compila con j# (e non è detto, per quello gli ho detto di fare la prova) allora è sufficiente crearsi una dll e richiamare direttamente i metodi da C# senza bisogno di bestemmiare con JNI.
JNI/COM. In ogni caso sappi che non sarà una bella esperienza. Se l'input e l'output non sono particolarmente strutturati (e quindi la (de)serialization non costa troppo) puoi considerare l'uso di socket o ancora meglio named pipes, ma quello richiederebbe una serie di stub in java wrappati in una classe per gestire i messaggi...Visto che non credo che la questione sia per un progettino scolastico ti sconsiglio invece di guardare IKVM et similia.
Grazie, vediamo se riesco a wrappare tutto cio' che mi serve in un COM
hai già provato ad usare il j# redistributable?
Ho provato a perderci un po' di tempo, ma non sembra esserci modo di fargli digerire il malloppo. Troppe specificita'.
In ogni caso grazie.
Ho la necessita' di richiamare una funzione (tante in realta') scritta in Java da parte di un mio programma C#
Dispongo dei sorgenti di entrambi, ma non e' mia facolta' ne volonta' cambiare il codice Java monolitico e immenso che mi si para davanti.
Inoltre ho la necessita' di una discreta velocita', nel senso che dovro' richiamare le funzioni Java per tante volte. Sono decisamente veloci, quindi mi seccherebbe dover spendere piu' tempo per i passaggi di informazioni piuttosto che per i calcoli veri e propri, dato che il flusso e' gia' su un percorso critico.
Idee possibili?
JNI. Incapsuli la creazione della JVM e le funzioni che vuoi richiamare in una libreria dinamica fatta nel buon vecchio C e sei a posto. Per le performace dipende da cosa scambi. L'overhead dovuto all'invocazione di metodi o funzioni che ricevono e restituiscono primitivi, Buffer o array di primitivi è nell'ordine del nullosecondo. Ricorda di fare un cache nel codice nativo dei metodi che vuoi invocare se prevedi che siano invocati molte volte in modo da eliminare del tutto il tempo dovuto al lookup.
Comunque è il classico "gioco da ragazzi" anche nel caso in cui sia la prima esperienza: una volta scritta la prima invocazione le altre sono tutte uguali, cambiano solo i nomi.
Ma non potresti compilare il codice Java come eseguibile... quindi lanciare questo eseguibile MENTRE lanci l'altro in C#?
a questo punto credo sia una cavolata implementare una state machine condivisa in modo che i due programmi possano "parlare" rapidamente tramite comandi, o no?:stordita:
Onde comprendere la "portata" del compito che attende chi voglia scontrarsi con l'immane difficoltà di invocare dei metodi Java con JNI posto del codice:
#include <jni.h>
#include <windows.h>
#include <stdio.h>
JNIEnv *env;
JavaVM *jvm;
HINSTANCE hvm;
jmethodID methodId;
jobject instance;
void createJVM(void);
void disposeJVM(void);
void precache(void);
int main() {
createJVM();
precache();
jint sum = (*env)->CallIntMethod(env, instance, methodId, 100, 33);
printf("La somma di 10 e 20 e' %d\n", sum);
disposeJVM();
}
void precache(void) {
jclass instanceClass = (*env)->FindClass(env, "it/bingo/bongo/JavaFunctions");
jmethodID constructor = (*env)->GetMethodID(env, instanceClass, "<init>", "()V");
instance = (*env)->NewObject(env, instanceClass, constructor);
methodId = (*env)->GetMethodID(env, instanceClass, "sum", "(II)I");
}
void createJVM() {
hvm = LoadLibrary("c:\\programmi\\java\\jre\\bin\\client\\jvm.dll");
FARPROC createJVM = GetProcAddress(hvm, "JNI_CreateJavaVM");
JavaVMInitArgs vmArgs;
vmArgs.version = 0x00010002;
vmArgs.nOptions = 0;
(*createJVM)(&jvm, (void**)&env, &vmArgs);
}
void disposeJVM() {
if(jvm != NULL) (*jvm)->DestroyJavaVM(jvm);
if(hvm != NULL) FreeLibrary(hvm);
}
Visto che si tratta di roba terra terra prima di andare a impegolarsi con soluzioni esoteriche almeno un tentativo lo farei. Magari giusto per fare un "benchmarkino" e vedere se è papabile o no.
Ma non potresti compilare il codice Java come eseguibile... quindi lanciare questo eseguibile MENTRE lanci l'altro in C#?
a questo punto credo sia una cavolata implementare una state machine condivisa in modo che i due programmi possano "parlare" rapidamente tramite comandi, o no?:stordita:
Questa era un'alternativa, che pero' prevede di mettere mano al codice Java, che e' condiviso da piu' gruppi di lavoro (che lo usano nativamente). Se possibile volevamo evitare questa strada.
Onde comprendere la "portata" del compito che attende chi voglia scontrarsi con l'immane difficoltà di invocare dei metodi Java con JNI posto del codice:
Grazie per il codice. Visto cosi' sembra semplice.
Non so se c'e' una JNI gia' managed per C#, ora cerco. Alla peggio prendo il tuo codice C++ royalty free ( :D ) e lo impacco in un Maresciallo.
!k-0t1c!
14-06-2009, 12:21
Grazie per il codice. Visto cosi' sembra semplice.
Non so se c'e' una JNI gia' managed per C#, ora cerco. Alla peggio prendo il tuo codice C++ royalty free ( :D ) e lo impacco in un Maresciallo.
Se il codice di PGI ti basta e non hai esigenze più elaborate allora tanto vale che ti faccia un mixed mode assembly senza stare a perdere tempo con marshaling o P/Invoke ;)
vBulletin® v3.6.4, Copyright ©2000-2026, Jelsoft Enterprises Ltd.