2011-07-27 13 views
5

Sono in procinto di fare un po 'di Java < ->. NET codice di interoperabilità utilizzando una libreria nativa tra di loro, finora le cose stanno andando abbastanza bene.Java JNIEnv Segmentation Fault

Tuttavia, per qualche motivo non è possibile eseguire alcun metodo in JNIEnv.

System::String^ JNIStringToNet(JNIEnv * env, jstring js) 
{ 
    const char *buf = env->GetStringUTFChars(js, 0); // segfault 

ora posso passare variabili avanti e indietro e fare tutti gli altri tipi di comunicazione, quindi mi sto immaginando che non ho inizializzato correttamente questo o qualcosa del genere.

sto caricando in questo modo:

this.Lib = (LibHandler)Native.loadLibrary(this.Name, LibHandler.class);  

(io preferisco Native.loadLibrary perché sembra mi permette di fare di più con più facile, come la condivisione di classe tra più librerie e sgancio e manovra di riaggancio è dalla JVM al volo).

Edit:

Scherzi a qualsiasi metodo:

std::cout << "Getting version:" << std::endl; 
std::cout << env->GetVersion() << std::endl; 

Ottenere versione:

(segfault)

Tutte le idee su WHT MEnv sarebbe SEGFAULT per ogni metodo? Questo dovrebbe essere impostato dalla JVM, corretto?

Edit 2:

Questa è un'applicazione Java che chiama una libreria C++ che si interfaccia con una libreria .NET (quindi è un CLR compilato libreria C++, se questo fa alcuna differenza), per limitare eventuali fattori esterni non sto nemmeno chiamando la DLL di .NET, ma semplicemente convertendo stringhe che tornano indietro (o bene ... provando).

Così, per esempio da Java:

this.Lib = (LibHandler)Native.loadLibrary(this.Name, LibHandler.class); 
this.Lib.myCPPMethod(); // Segmentation fault during this call, JVM crashes. 

curioso se fosse il CLR che stava causando esso: la compilazione CLR disabili e messo a nudo tutto ciò che era legato CLR, lo fa ancora.

Edit 3:

Got a discarica:

# 
# A fatal error has been detected by the Java Runtime Environment: 
# 
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000000000000, pid=1596, tid=7248 
# 
# JRE version: 6.0_23-b05 
# Java VM: Java HotSpot(TM) 64-Bit Server VM (19.0-b09 mixed mode windows-amd64 compressed oops) 
# Problematic frame: 
# C 0x0000000000000000 

Quindi sì, si presenta come la JVM non mi sta dando accesso alla memoria per qualche motivo.

Edit 4:

chiamata effettiva:

JNIEXPORT jstring JNICALL Query(JNIEnv * env, jobject jobj, jstring start, jstring end) 
{ 
    std::cout << "Getting version:" << std::endl; 
    jint j = env->GetVersion(); 
    return jstring("test"); 
} 

Edit 5:

funziona con il sistema.loadLibrary:

JNIEXPORT void JNICALL Java_LibTest_T(JNIEnv *env, jobject jobj) 
{ 
    std::cout << "Getting version:" << std::endl; 
    jint j = env->GetVersion(); 
    std::cout << j << std::endl; 
} 

uscita:

java -Djava.library.path="(dir)\lib\64" EntryPoint 
Getting version: 
65542 

Ack! Intendo dire alcuni progressi, ma non riesco a scaricare le librerie dalla JVM che sono caricate in System.loadLibrary posso?

Fondamentalmente ho bisogno di essere in grado di sganciare queste librerie dalla JVM e di scambiarle, oltre a questo hanno tutti bisogno di "condividere" una singola classe e poter essere associate alla classe in fase di esecuzione ... che è un po 'il motivo per cui sono andato con Native.loadLibrary.

Attualmente mi fare questo:

caricare la DLL:

this.Lib = (LibHandler)Native.loadLibrary(this.Name, LibHandler.class); 

sganciarla:

this.Lib = null; 
Runtime.getRuntime().gc(); // Force the JVM to drop it immediately. 

Classe li passo per caricare in:

public interface LibHandler extends Library{ 
    void T(); 
} 

In qualsiasi modo lavorare in modo simile a System.lo adLibrary?

Edit 6:

Non esitate a chiamare me muto, sto usando JNA, NON JNI, che è completamente diverso e un enorme fonte dei miei problemi .... c'è un modo fare questo con JNI? O posso ottenere JNIEnv per registrarmi in qualche modo con JNA? Immagino di poter rilasciare JNI dalla libreria C++ e utilizzare le stringhe?

Tornerò con questo domani.

+0

si può dare un po 'di più dettaglio? Questo java chiama il codice .Net tramite una libreria nativa, oppure .NET chiama Java tramite una libreria nativa? –

+0

Stai provando a chiamare JVM da .Net o viceversa? Se è il primo, è necessario utilizzare l'API di invito (esegui la ricerca su Google). Nello specifico, devi chiamare JNI_CreateJavaVM –

+0

Scusaci, modifica 2 indirizzi che ora. :) È una chiamata da Java a una DLL C++. – StrangeWill

risposta

0

Beh, mi sento male.

Native.loadLibrary == JNA.

System.loadLibrary == JNI.

Lo scopo della JNA è quello di non richiedere alcuna reale conoscenza dell'ambiente JVM, in modo da poter eseguire le librerie native come è, così invece di jstring è possibile utilizzare char * ...

Problemi correlati