Use dll files in java

C# to Java (вызов C# dll из Java)

Доброго времени суток!
Помучив немного хабра поиск не нашел подобных тем, в связи с чем создал свою.

Немного лирики:
Имеем шарповскую библиотеку, в которой лежат необходимые для работы методы. Необходимо этими методами воспользоваться из Java программы.

Пример первый

Сначала покажу простой пример.
Имеем примитивную dll на шарпе, назовем ее SharpClass:

public class CSharpHelloWorld < public CSharpHelloWorld() < >public void displayHelloWorld() < Console.WriteLine("Hello World From C#!"); >> 

Будем собирать этот класс в сборку:
Открываем командную строку, и прописываем такую команду (предварительно нужно зайти в директорию с нашим SharpClass.cs файлом): csc \t: module SharpClass.cs. Если команда не работает, то перед ее запуском нужно выполнить бат-файл, у меня он находится здесь — C:\Program Files\Microsoft Visual Studio 9\VC\bin\vcvars32.bat
После выполнения сей процедуры мы получим файл SharpClass.netmodule, находящийся в одной папке с исходником.

Для связи между .NET и JVM нужен враппер (обертка для получения unmanaged кода). Создадим обертку из с++ с использованием явовской библиотеки jni.h и майкрософтовской библиотеки mscorlib.dll
Создаем с++ обертку:

#using #using "SharpClass.netmodule" using namespace System; __gc class HelloWorldC < public: CSharpHelloWorld __gc *t; HelloWorldC() < t = new CSharpHelloWorld(); >void method() < t ->displayHelloWorld(); > >; 

После написания этого кода необходимо указать ссылку на mscorlib.dll. Для этого заходим в настройки проекта и сначала находим General, где в пункте Common Language Runtime Support выбираем Common Language Runtime Support, Old Syntax (/clr:oldSyntax), после этого жмем References (ссылки) и добавляем новую — во вкладке .NET будет искомая dll (так было в VS2005).

#include "C:\Program Files\Java\jdk1.6.0_02\include\jni.h" #include "HelloWorld.h" #include "1.cpp" JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject) < HelloWorldC* t = new HelloWorldC(); t->method(); > 
JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject); 

И последний хедер генерируется при помощи Java из командной строки запуском команды — javah -jni «имя класса без кавычек и без .class» (создавать его естественно нужно после компиляции ява программы, иначе сам класс просто не появится). В файлах 1.h и 2.cpp код также взят из последнего хедера.

#ifndef _Included_HelloWorld #define _Included_HelloWorld #ifdef __cplusplus extern "C" < #endif /* * Class: HelloWorld * Method: displayHelloWorld * Signature: ()V */ JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject); #ifdef __cplusplus >#endif #endif 

После этого весь c++ проект строится в dll. Назовем его HelloWorld.dll.

Читайте также:  Java text dateformat format

Теперь переходим к Яве. Вот простой код для вызова нашей HelloWorld.dll:

import java.io.*; class HelloWorld < public native void displayHelloWorld(); static < System.load("C:\\Java_C#\\JavaApplication1\\HelloWorld.dll"); >public static void main(String[] args) < new HelloWorld().displayHelloWorld(); >> 

Вот собственно все готово. Ну и наш SharpClass.netmodule также необходимо перенести в папку с загружаемой сишной dll.

Пример второй

В первом примере рассматривался простой случай просто с выводом текста на экран. Сейчас рассмотрим случай, когда функция на C# принимает параметры и возвращает значение.
C# класс:

using System; using System.Collections.Generic; using System.Text; public class CSharpToJava < public CSharpToJava() < >public String returnValue(String value) < string ss = " cvb"; String answer = value+ss; return answer; >> 

Java приложение, использующее этот класс:

public class Main < public native String returnValue(String value); static < System.load("C:\\Java\\SharpToJava\\CSharpToJava.dll"); >public static void main(String[] args) < String value="Privet"; String val = new Main().returnValue(value); System.out.println(val); >> 

После этого создаем хедер для с++ с помощью команды, описанной в первом примере.
Далее создаем с++ обертку, которая таскает переменные из одного конца в другой :). Будет 3 файла — wrapper.cpp, CSharpToJava.cpp, Main.h (последний получается выполнением команды javah -jni над явовским классом)

#include #include #using //Подключение майкрософтовской библиотеки для создания native кода #using "CSharpClass.netmodule" //Подключение шарповской сборки, в который содержится вызываемая из явы функция using namespace std; using namespace System; //Создаем класс-обертку для преобразования шарповской функции в native код __gc class SendValue < public: CSharpToJava __gc *t; //CSharpToJava - класс шарпа. //t - указатель на него из с++ SendValue() < t = new CSharpToJava(); >String __gc* method(String __gc* value) < return (t ->returnValue(value)); > >; 
#include "C:\Program Files\Java\jdk1.6.0_02\include\jni.h" #include "Main.h" #include "wrapper.cpp" #include #include using namespace System::Runtime::InteropServices; //нужен для использования Marshal class, который делает перевод из String* в const Char* using namespace std; //Main функция //Экспортируемая функция из явы //Заголовок получается путем выполнения команды javah -jni "имя класса, пишется без кавычек и .class" JNIEXPORT jstring JNICALL Java_Main_returnValue (JNIEnv* env, jobject, jstring jvalue) < //Получение переменной jvalue, передаваемой из явы и присвоение сишной переменной value с типом String __gc* String __gc* value=env->GetStringUTFChars(jvalue,0); //Получение указателя на объект класса SendValue, который описан в wrapper.cpp SendValue* t = new SendValue(); //Получение значения из шарповской функции и присвоение его переменной val типа String __gc* String __gc* val = t->method(value); //Преобразование типа String* в const char* char* str2 = (char*)(void*)Marshal::StringToHGlobalAnsi(val); jstring jval; //Преобразование типа const char* в jstring, который требует вернуть функция явы jval=env->NewStringUTF(str2); //Возвращение явовской переменной return jval; > 
/* DO NOT EDIT THIS FILE - it is machine generated */ /* Header for class Main */ #ifndef _Included_Main #define _Included_Main #ifdef __cplusplus extern "C" < #endif /* * Class: Main * Method: returnValue * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_Main_returnValue (JNIEnv *, jobject, jstring); #ifdef __cplusplus >#endif #endif 

Заключение

Ну вот собственно и все. Данный код писал и испытывал 2 года назад, а сюда все никак руки не доходили написать. Когда разбирался с этой задачей, пытался просить помощи на одном форуме. Пока помощи просил, сам немного разобрался и написал свое решение.

Полезные ссылки

Источник

C# to Java (вызов C# dll из Java)

Доброго времени суток!
Помучив немного хабра поиск не нашел подобных тем, в связи с чем создал свою.

Немного лирики:
Имеем шарповскую библиотеку, в которой лежат необходимые для работы методы. Необходимо этими методами воспользоваться из Java программы.

Пример первый

Сначала покажу простой пример.
Имеем примитивную dll на шарпе, назовем ее SharpClass:

public class CSharpHelloWorld < public CSharpHelloWorld() < >public void displayHelloWorld() < Console.WriteLine("Hello World From C#!"); >> 

Будем собирать этот класс в сборку:
Открываем командную строку, и прописываем такую команду (предварительно нужно зайти в директорию с нашим SharpClass.cs файлом): csc \t: module SharpClass.cs. Если команда не работает, то перед ее запуском нужно выполнить бат-файл, у меня он находится здесь — C:\Program Files\Microsoft Visual Studio 9\VC\bin\vcvars32.bat
После выполнения сей процедуры мы получим файл SharpClass.netmodule, находящийся в одной папке с исходником.

Для связи между .NET и JVM нужен враппер (обертка для получения unmanaged кода). Создадим обертку из с++ с использованием явовской библиотеки jni.h и майкрософтовской библиотеки mscorlib.dll
Создаем с++ обертку:

#using #using "SharpClass.netmodule" using namespace System; __gc class HelloWorldC < public: CSharpHelloWorld __gc *t; HelloWorldC() < t = new CSharpHelloWorld(); >void method() < t ->displayHelloWorld(); > >; 

После написания этого кода необходимо указать ссылку на mscorlib.dll. Для этого заходим в настройки проекта и сначала находим General, где в пункте Common Language Runtime Support выбираем Common Language Runtime Support, Old Syntax (/clr:oldSyntax), после этого жмем References (ссылки) и добавляем новую — во вкладке .NET будет искомая dll (так было в VS2005).

#include "C:\Program Files\Java\jdk1.6.0_02\include\jni.h" #include "HelloWorld.h" #include "1.cpp" JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject) < HelloWorldC* t = new HelloWorldC(); t->method(); > 
JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject); 

И последний хедер генерируется при помощи Java из командной строки запуском команды — javah -jni «имя класса без кавычек и без .class» (создавать его естественно нужно после компиляции ява программы, иначе сам класс просто не появится). В файлах 1.h и 2.cpp код также взят из последнего хедера.

#ifndef _Included_HelloWorld #define _Included_HelloWorld #ifdef __cplusplus extern "C" < #endif /* * Class: HelloWorld * Method: displayHelloWorld * Signature: ()V */ JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject); #ifdef __cplusplus >#endif #endif 

После этого весь c++ проект строится в dll. Назовем его HelloWorld.dll.

Теперь переходим к Яве. Вот простой код для вызова нашей HelloWorld.dll:

import java.io.*; class HelloWorld < public native void displayHelloWorld(); static < System.load("C:\\Java_C#\\JavaApplication1\\HelloWorld.dll"); >public static void main(String[] args) < new HelloWorld().displayHelloWorld(); >> 

Вот собственно все готово. Ну и наш SharpClass.netmodule также необходимо перенести в папку с загружаемой сишной dll.

Пример второй

В первом примере рассматривался простой случай просто с выводом текста на экран. Сейчас рассмотрим случай, когда функция на C# принимает параметры и возвращает значение.
C# класс:

using System; using System.Collections.Generic; using System.Text; public class CSharpToJava < public CSharpToJava() < >public String returnValue(String value) < string ss = " cvb"; String answer = value+ss; return answer; >> 

Java приложение, использующее этот класс:

public class Main < public native String returnValue(String value); static < System.load("C:\\Java\\SharpToJava\\CSharpToJava.dll"); >public static void main(String[] args) < String value="Privet"; String val = new Main().returnValue(value); System.out.println(val); >> 

После этого создаем хедер для с++ с помощью команды, описанной в первом примере.
Далее создаем с++ обертку, которая таскает переменные из одного конца в другой :). Будет 3 файла — wrapper.cpp, CSharpToJava.cpp, Main.h (последний получается выполнением команды javah -jni над явовским классом)

#include #include #using //Подключение майкрософтовской библиотеки для создания native кода #using "CSharpClass.netmodule" //Подключение шарповской сборки, в который содержится вызываемая из явы функция using namespace std; using namespace System; //Создаем класс-обертку для преобразования шарповской функции в native код __gc class SendValue < public: CSharpToJava __gc *t; //CSharpToJava - класс шарпа. //t - указатель на него из с++ SendValue() < t = new CSharpToJava(); >String __gc* method(String __gc* value) < return (t ->returnValue(value)); > >; 
#include "C:\Program Files\Java\jdk1.6.0_02\include\jni.h" #include "Main.h" #include "wrapper.cpp" #include #include using namespace System::Runtime::InteropServices; //нужен для использования Marshal class, который делает перевод из String* в const Char* using namespace std; //Main функция //Экспортируемая функция из явы //Заголовок получается путем выполнения команды javah -jni "имя класса, пишется без кавычек и .class" JNIEXPORT jstring JNICALL Java_Main_returnValue (JNIEnv* env, jobject, jstring jvalue) < //Получение переменной jvalue, передаваемой из явы и присвоение сишной переменной value с типом String __gc* String __gc* value=env->GetStringUTFChars(jvalue,0); //Получение указателя на объект класса SendValue, который описан в wrapper.cpp SendValue* t = new SendValue(); //Получение значения из шарповской функции и присвоение его переменной val типа String __gc* String __gc* val = t->method(value); //Преобразование типа String* в const char* char* str2 = (char*)(void*)Marshal::StringToHGlobalAnsi(val); jstring jval; //Преобразование типа const char* в jstring, который требует вернуть функция явы jval=env->NewStringUTF(str2); //Возвращение явовской переменной return jval; > 
/* DO NOT EDIT THIS FILE - it is machine generated */ /* Header for class Main */ #ifndef _Included_Main #define _Included_Main #ifdef __cplusplus extern "C" < #endif /* * Class: Main * Method: returnValue * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_Main_returnValue (JNIEnv *, jobject, jstring); #ifdef __cplusplus >#endif #endif 

Заключение

Ну вот собственно и все. Данный код писал и испытывал 2 года назад, а сюда все никак руки не доходили написать. Когда разбирался с этой задачей, пытался просить помощи на одном форуме. Пока помощи просил, сам немного разобрался и написал свое решение.

Полезные ссылки

Источник

Оцените статью