2011-07-27 18 views
5

Je suis en train de faire Java < ->. NET Interop code en utilisant une bibliothèque native entre eux, jusqu'à présent, les choses se passent plutôt bien.Java JNIEnv Segmentation Fault

Cependant, pour une raison quelconque, je ne peux pas exécuter de méthodes sous JNIEnv.

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

et-vient maintenant je peux passer des variables et faire tous les autres types de communication, donc je suis comprendre je n'ai pas initialisé correctement ce ou quelque chose.

Je suis en train de charger comme ceci:

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

(je préfère Native.loadLibrary parce qu'il semble me permettre de faire plus avec facilité, comme le partage des classes entre plusieurs bibliothèques et décrochement et rehooking il de la JVM à la volée).

Edit:

sérieusement toute méthode:

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

Version Obtenir:

(segfault)

Toutes les idées sur WHT JNIEnv serait Segfault pour chaque méthode? Cela devrait être mis en place par la JVM, correct?

Edit 2:

Ceci est une application Java qui appelle une bibliothèque C++ qui interface avec une bibliothèque .NET (il est donc un CLR compilé en C++ bibliothèque, si cela fait une différence), de limiter tous les facteurs externes que je n'appelle même pas la DLL de .NET mais juste convertissant des chaînes qui rentrent en arrière (ou bien ... essayant).

Ainsi, par exemple à partir de Java:

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

curieux de savoir s'il était le CLR qui a été à l'origine il: Désactivé compilation clr et tout dépouillé qui était CLR lié, le fait toujours.

Edit 3:

Got à basculantes:

# 
# 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 

Alors oui, on dirait que la machine virtuelle Java ne me donne pas accès à la mémoire pour une raison quelconque.

Edit 4:

appel réel:

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:

Works avec système.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; 
} 

Sortie:

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

Ack! Je veux dire quelques progrès, mais je ne peux pas décharger les bibliothèques de la JVM qui sont chargées dans System.loadLibrary puis-je? Je dois essentiellement être capable de décrocher ces bibliothèques de la JVM et de les échanger, en plus de cela, elles doivent toutes "partager" une seule classe et pouvoir être liées à la classe à l'exécution ... ce qui est un peu pourquoi je suis allé avec Native.loadLibrary.

Actuellement je fais ceci:

charge la DLL:

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

Décrocher il:

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

classe I les charger dans:

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

De toute façon travailler de manière similaire avec System.lo adLibrary?

Modifier 6:

Ne hésitez pas à me appeler stupide, je suis à l'aide de la JNA, pas JNI, ce qui est tout à fait différent et une énorme source de mes problèmes .... est-il un moyen faire cela avec JNI? Ou puis-je demander à JNIEnv de s'inscrire auprès de la JNA? Je suppose que je peux laisser tomber JNI de la bibliothèque C++ et utiliser directement wstrings?

Je reviendrai avec ça demain.

+0

Pouvez-vous donner un peu plus détail? Est-ce java appelant le code .Net via une bibliothèque native, ou .NET appelant Java via une bibliothèque native? –

+0

Essayez-vous d'appeler la JVM à partir de .Net ou vice-versa? Si c'est le cas, vous devez utiliser l'API Invocation (faire une recherche sur Google). Plus précisément, vous devez appeler JNI_CreateJavaVM –

+0

Désolé, à ce sujet, éditez 2 adresses maintenant. :) C'est un appel de Java à une DLL C++. – StrangeWill

Répondre

0

Eh bien, je me sens mal.

Native.loadLibrary == JNA.

System.loadLibrary == JNI.

Le but de la JNA est de ne pas exiger une connaissance réelle de l'environnement machine virtuelle Java, de sorte que vous pouvez exécuter des bibliothèques natives comme il est, donc au lieu de jstring vous pouvez utiliser char * ...