Tengo un ensamblado de .NET de terceros y una gran aplicación de Java. Necesito llamar a mothods proporcionados por la biblioteca de clases .NET desde la aplicación Java. El ensamblaje no está habilitado para COM. He buscado la red y hasta ahora tengo el siguiente:Llamar al ensamblado de .NET desde Java: bloqueos de JVM
código C# (cslib.cs):
using System;
namespace CSLib
{
public class CSClass
{
public static void SayHi()
{
System.Console.WriteLine("Hi");
}
}
}
compilado con (utilizando .NET 3.5, pero lo mismo sucede cuando se utiliza 2.0) código
csc /target:library cslib.cs
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();
}
compilado con (utilizando VC 2008 herramientas, pero º e igual ocurre cuando se utilizan herramientas 2003):
cl /clr /LD clib.cpp
mt -manifest clib.dll.manifest -outputresource:clib.dll;2
código Java (CallCS.java):
class CallCS {
static {
System.loadLibrary("clib");
}
private static native void callCS();
public static void main(String[] args) {
callCS();
}
}
Cuando trato de ejecutar la clase de Java, se bloquea la máquina virtual de Java mientras se invoca el método (es capaz de cargar la biblioteca):
# # 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
Sin embargo, si se crea una aplicación CPP normal que carga clib.dll y llama a los Java_CallCS_callCS función exportada, todo está bien. He intentado esto tanto en entornos x86 como x64 y el resultado es el mismo. No he probado otras versiones de Java, pero necesito el código para ejecutar en 1.5.0.
Por otra parte, si modifico clib.cpp a llamar a los métodos del sistema todo funciona bien incluso 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");
}
Para terminar:
- soy capaz de llamar a los métodos del sistema de Java -> clib.dll -> mscorlib.dll
- PUEDO llamar a cualquier método desde CPPApp -> clib.dll -> cslib.dll
- No puedo llamar a ningún método desde Java -> clib.dll - > cs lib.dll
Soy consciente de una solución alternativa que utiliza 1. anterior - Puedo usar la reflexión para cargar el assmebly e invocar los métodos deseados utilizando solo llamadas al sistema, pero el código se vuelve complicado y espero una mejor solución.
Conozco el proyecto dotnetfromjava, que utiliza el método de reflexión, pero prefiere no agregar más complejidad de la necesaria. Usaré algo así si no hay otra manera, sin embargo.
También he consultado ikvm.net, pero tengo entendido que usa su propia JVM (escrita en C#) para hacer la magia. Sin embargo, ejecutar toda la aplicación Java en su máquina virtual no es una opción para mí.
Gracias.
El código C++ ++ es en realidad C++/CLI ¿verdad? – Gili
Sí, se especifica la opción/clr – Kcats