De l'appelant .NET de l'assemblée de l'île de Java: JVM se bloque

J'ai une troisième partie .NET de l'Assemblée et une grande application Java. J'ai besoin d'appeler réflexes fournis par le .NET de la bibliothèque de classes de l'application Java. L'assemblée n'est pas COM-activé.
J'ai cherché sur le net et pour l'instant j'ai le texte suivant:

Code C# (cslib.cs):

using System;

namespace CSLib
{
    public class CSClass
    {
        public static void SayHi()
        {
            System.Console.WriteLine("Hi");
        }
    }
}

compilé (à l'aide .net 3.5, mais le même phénomène se produit quand 2.0 est utilisé):

csc /target:library cslib.cs

De code C++ (clib.cpp):

#include <jni.h>
#using <CSLib.dll>

using namespace CSLib;

extern "C" _declspec(dllexport) void Java_CallCS_callCS(JNIEnv* env, jclass cls) {
    CSLib::CSClass::SayHi();
}

compilé (à l'aide de VC 2008 outils, mais le même phénomène se produit lors de 2003 sont les outils utilisés):

cl /clr /LD clib.cpp
mt -manifest clib.dll.manifest -outputresource:clib.dll;2

Code Java (CallCS.java):

class CallCS {
    static {
       System.loadLibrary("clib");
    }
    private static native void callCS();
    public static void main(String[] args) {
        callCS();
    }
}

Lorsque j'essaie d'exécuter la classe java, la machine virtuelle Java plante lors de l'invocation de la méthode (il est en mesure de charger la bibliothèque):

# 
# Une erreur inattendue a été détectée par l'Environnement d'Exécution Java: 
# 
# Erreur interne (0xe0434f4d), pid=3144, tid=3484 
# 
# Java VM: Java HotSpot(TM) Client VM (10.0-b19 en mode mixte, le partage de windows-x86) 
# Problématiques cadre: 
# C [kernel32.dll+0x22366] 
# 
... 
Java cadres: (J=compilé en code Java, j=interprété, Vv=VM code) 
j CallCS.callCS()V+0 
j CallCS.principale([Ljava/lang/String;)V+0 
v ~StubRoutines::call_stub 

Cependant, si je crée une plaine rpc application qui charge clib.dll et appelle la fonction exportée Java_CallCS_callCS, tout est OK.
J'ai essayé sur les deux environnements x86 et x64 et le résultat est le même. Je n'ai pas essayé d'autres versions de Java, mais j'ai besoin le code à exécuter sur 1.5.0.

De plus, si je modifie clib.cpp pour appeler Système d'méthodes tout fonctionne très bien, même à partir de Java:

#include <jni.h>
#using <mscorlib.dll>

using namespace System;

extern "C" _declspec(dllexport) void Java_CallCS_callCS(JNIEnv* env, jclass cls) {
    System::Console::WriteLine("It works");
}

Pour conclure:

  1. Je suis en MESURE de Système d'appel des méthodes de Java -> clib.dll -> mscorlib.dll
  2. Je suis en MESURE d'appeler les méthodes de CPPApp -> clib.dll -> cslib.dll
  3. Je suis INCAPABLE d'appeler les méthodes de Java -> clib.dll -> cslib.dll

Je suis conscient d'une solution de contournement qui utilise 1. ci-dessus - que je peux utiliser la réflexion pour charger la assmebly et d'appeler désiré méthodes utilisant uniquement les appels Système, mais le code est illisible et je suis l'espoir d'une meilleure solution.

Je sais à propos de dotnetfromjava projet, qui utilise la méthode de réflexion, mais qui préfèrent ne pas ajouter plus de complexité que de besoin. Je vais utiliser quelque chose comme cela si il n'y a pas d'autre moyen, cependant.

J'ai regardé ikvm.net aussi, mais ma compréhension est qu'il utilise sa propre JVM (écrit en C#) pour faire de la magie. Toutefois, l'exécution de l'ensemble de l'application Java sous son VM est pas une option pour moi.

Grâce.

Le code C++ est en fait C++/CLI droit?
Oui, le /clr option est spécifiée

OriginalL'auteur Kcats | 2008-09-26