Usar en Java DLL realizada con C#

Tengo un programa realizado en C# que quiero convertir en una DLL para luego usarla en una aplicación Java.

He visto en diversas páginas que es necesario utilizar un solución intermedia con C++ que sirva de puente entre la aplicación Java y la dll en C#. Lo he intentado pero no consigo que funcione.

Se me ha ocurrido utilizar la dll generada en C# en un proyecto C++, generando una nueva DLL que utilizaría en el proyecto Java.

Los frameworks de desarrollo que estoy utilizando son: Spring, Microsoft Visual C# 2008 Express Edition y Visual C++ 2008 Express Edition.

¿Hay una forma más sencilla de hacerlo?

Respuesta
1

C# Y todas las herramientas .Net, tan solo crean un código Pre-Procesado, llamado IL, pues sus siglas en ingles (Intermedial Language), y hacen sus llamados a funciones mediante objetos COM y las dll de c# son biblioteclas de clases, es por esta razón que no vas a poder hacer llamados a bibliotecas .dll desde otras aplicaciones que no sean .NET.
Mi recomendación es que tomes las funciones que creaste en el dll de C# y las insertes en un nuevo proyecto como Librería dinámica (.dll) de VC++ (el mismo Visual studio 2008 te sirve.)
Recuerda que las funciones extrenas deben cumplir con el estándar del viejo WinAPI y debes agregar las declaraciones en el archivo .DEP del proyecto.
No es tan difícil, si bajas un ejemplo de un proyecto .dll básico de visual Studio
Suerte!

Hola,

Gracias por tu respuesta. El mismo día que la recibí intenté responderte pero hubo un problema y no se si te llego.

No entiendo a que te refieres con que deben cumplir con el estándar del viejo WinAPI y lo de agregar las declaraciones en el archivo .DEP del proyecto.

Ahora mismo mi problema está en la llamada que se hace desde la función C++ al método en C#:

String^ result = DataType::Test::tranform("Brigde Java to C# DLL");

Si esta llamada la hago en el método main del proyecto, genero un exe y lo ejecuto funciona perfectamente.

int _tmain(int argc, _TCHAR* argv[])
{

String^ result = DataType::Test::tranform("Brigde Java to C# DLL");

}

En cambio si la invoco desde la función que se llamaría desde Java

/*
* Class: com_mycompany_dll_Test
* Method: SendAndReceiveString
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_mycompany_dll_Test_SendAndReceiveString
(JNIEnv *env, jobject, jstring input){

const char *nativeText = env->GetStringUTFChars(input, JNI_FALSE);
String^ ssText = gcnew String(nativeText);

String^ result = DataType::Test::tranform("Brigde Java to C# DLL");

const char *nativeResult = (const char*)(Marshal::StringToHGlobalAnsi(result)).ToPointer();
jstring jsResult = env->NewStringUTF(nativeResult)

}

Si sustituyo la línea que invoca al método de la dll en C# y pongo

String^ result = gcnew String("Brigde Java to C# DLL");

la invocación desde Java a la dll funciona perfectamente.

El error que me da es el siguiente:

#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (0xe0434f4d), pid=7024, tid=6768
#
# JRE version: 6.0_22-b04
# Java VM: Java HotSpot(TM) Client VM (17.1-b03 mixed mode windows-x86 )
# Problematic frame:
# C [kernel32.dll+0x12fd3]
#
# An error report file with more information is saved as:
# D:\WorkspaceSTS38\TestLibrary\hs_err_pid7024.log
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

Voy explicarte lo que te comente anteriormente.

Los Archivos .DLL poseen una Interfaz estándar para poder efectuar las llamadas a las funciones que poseen dentro:

WINAPI es solo la Definición del tipo para ese estándar (Windef.h):
#define WINAPI      __stdcall

Te voy a mostrar un ejemplo de Código Basado en las funciones ZipComp y ZipDecomp que están dentro de una librería dinámica llamada SEC.DLL (imagen de arriba).
Código.:
/////////////////////////////////////////////////////////////////////////////
// Public C interface
BOOL WINAPI ZipComp(HWND hWndParent, BOOL * lSucess, LPCTSTR strFile)
{
    BOOL nRet=0;
    nRet = zipmain(0, strFile);
    lSucess = &nRet;
  return nRet ;
}
BOOL WINAPI ZipDecomp(HWND hWndParent, BOOL * lSucess, LPCTSTR strFile)
{
    BOOL nRet=0;
    nRet =     zipmain(1, strFile);
    lSucess = &nRet;
  return nRet ;
}

Al llamar esa librería dinámica desde Java o cualquier otro lenguaje, te va a funcionar.

Este vinculo te va a ayudar, aunque esta en ingles, si no dominas el idiona, lo puedes traducir con google traslator:

http://www.codeproject.com/Articles/1388/Calling-Conventions-Demystified 

**

Ahora, Con respecto al tu código...

- Por el comando:

int _tmain(int argc, _TCHAR* argv[])

Me doy cuenta que no generaste un .dll, sino un .exe con VC++ de Línea de comandos, el cual recibe un parámetro y devuelve otro al finalizar. La forma de llamar a diferentes funciones, sean creadas por ti, o del Sistema Operativo es como te explique anteriormente.

Mediante cualquier otra forma, vas a pasar trabajo y no te va a funcionar.

Por eso te mencionaba, que pasaras todas las funciones que hiciste en cSharp a un .DLL creado en VC++.

Suerte.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas