Aufruf der .NET-Assembly von Java aus: JVM stürzt ab

Ich habe eine .NET-Assembly eines Drittanbieters und eine große Java-Anwendung. Ich muss mothods aufrufen, die von der .NET-Klassenbibliothek aus der Java-Anwendung bereitgestellt werden. Die Assembly ist nicht COM-fähig. Ich habe das Netz durchsucht und bisher habe ich Folgendes:

C # -Code (cslib.cs):

using System;

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

Kompiliert mit (unter Verwendung von .net 3.5, aber dasselbe passiert, wenn 2.0 verwendet wird):

csc /target:library cslib.cs

C ++ Code (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();
}

Kompiliert mit (mit VC 2008-Tools, aber dasselbe passiert, wenn 2003-Tools verwendet werden):

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

Java-Code (CallCS.java):

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

Wenn ich versuche, die Java-Klasse auszuführen, stürzt die Java-VM beim Aufrufen der Methode ab (sie kann die Bibliothek laden):

#
# An unexpected error has been detected by Java Runtime Environment:
#
#  Internal Error (0xe0434f4d), pid=3144, tid=3484
#
# Java VM: Java HotSpot(TM) Client VM (10.0-b19 mixed mode, sharing windows-x86)
# Problematic frame:
# C  [kernel32.dll+0x22366]
#
...
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  CallCS.callCS()V+0
j  CallCS.main([Ljava/lang/String;)V+0
v  ~StubRoutines::call_stub

Wenn ich jedoch eine einfache CPP-Anwendung erstelle, die clib.dll lädt und die exportierte Funktion Java_CallCS_callCS aufruft, ist alles in Ordnung. Ich habe dies sowohl in x86- als auch in x64-Umgebungen versucht und das Ergebnis ist das gleiche. Ich habe noch keine anderen Java-Versionen ausprobiert, aber ich brauche den Code, um auf 1.5.0 zu laufen.

Wenn ich außerdem clib.cpp so ändere, dass nur Systemmethoden aufgerufen werden, funktioniert alles einwandfrei, auch von Java aus:

#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");
}

Einwickeln:

Ich bin in der Lage, Systemmethoden von Java aufzurufen -> clib.dll -> mscorlib.dllIch bin in der Lage, alle Methoden von CPPApp aufzurufen -> clib.dll -> cslib.dllIch kann keine Methoden von Java -> clib.dll -> cslib.dll aufrufen

Mir ist eine Problemumgehung bekannt, die den obigen Punkt 1 verwendet. Ich kann Reflection verwenden, um das Assmebly zu laden und gewünschte Methoden nur mit Systemaufrufen aufzurufen, aber der Code wird unordentlich und ich hoffe auf eine bessere Lösung.

Ich kenne das dotnetfromjava-Projekt, das die Reflektionsmethode verwendet, möchte aber nicht mehr Komplexität als nötig hinzufügen. Ich werde so etwas verwenden, wenn es keinen anderen Weg gibt.

Ich habe mir auch ikvm.net angeschaut, aber ich verstehe, dass es eine eigene JVM (geschrieben in C #) verwendet, um die Magie zu vollbringen. Das Ausführen der gesamten Java-Anwendung unter ihrer VM ist für mich jedoch keine Option.

Vielen Dank.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage