C#からJava(JavaからC#dllを呼び出す)

良い一日!
少し苦しめられたが、検索では似たようなトピックは見つかりませんでした。

ちょっとした歌詞:
作業に必要なメソッドが存在するSharpovライブラリがあります。 Javaプログラムからこれらのメソッドを使用する必要があります。

最初の例


最初に簡単な例を示します。
シャープにプリミティブなDLLがあります。これをSharpClassと呼びましょう。

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


このクラスをアセンブリにアセンブルします。
コマンドラインを開き、そのようなコマンドを記述します(最初に、SharpClass.csファイルがあるディレクトリに移動する必要があります): csc \ t:module SharpClass.cs 。 コマンドが機能しない場合、実行する前にbatファイルを実行する必要があります-C:\ Program Files \ Microsoft Visual Studio 9 \ VC \ bin \ vcvars32.bat
この手順を完了すると、ソースと同じフォルダーにあるSharpClass.netmoduleファイルが取得されます。

.NETとJVM間の通信には、ラッパー(アンマネージコードを取得するためのラッパー)が必要です。 jni.h javaライブラリとmscorlib.dll Microsoftライブラリを使用して、C ++からラッパーを作成しましょう
C ++ラッパーを作成します。

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


このコードを記述した後、mscorlib.dllへのリンクを提供する必要があります。 これを行うには、プロジェクト設定に移動し、最初に一般を見つけます。ここで、共通言語ランタイムサポートの項目で共通言語ランタイムサポート、古い構文(/ clr:oldSyntax)を選択し、参照(リンク)をクリックして新しいものを追加します-.NETタブdll(VS2005と同様)。

2.cpp
 #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(); } 


1.h
 JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject); 


最後のヘッダーは、コマンドを実行することでコマンドラインからJavaを使用して生成されます-javah -jni "class name without quotes and .class" (Javaプログラムのコンパイル後に作成する必要があります。そうしないと、クラス自体が表示されません)。 1.hおよび2.cppファイルでは、コードは最後のヘッダーからも取得されます。

HelloWorld.h
 #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に渡します。 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のあるフォルダーに移動する必要があります。

2番目の例


最初の例では、テキストを画面に出力するだけの単純なケースを検討しました。 次に、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); } } 


その後、最初の例で説明したコマンドを使用して、c ++のヘッダーを作成します。
次に、変数を一端から他端へドラッグするC ++ラッパーを作成します:)。 wrapper.cpp、CSharpToJava.cpp、Main.hの3つのファイルがあります(後者は、Javaクラスでjavah -jniコマンドを実行することにより取得されます)

wrapper.cpp
 #include #include <string> #using <mscorlib.dll> //     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)); } }; 


CSharpToJava.cpp
 #include "C:\Program Files\Java\jdk1.6.0_02\include\jni.h" #include "Main.h" #include "wrapper.cpp" #include #include <string> 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; } 


Main.h
 /* 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年前にこのコードを書いてテストしましたが、ここではまだ誰も手に入れることができませんでした。 このタスクを処理するとき、1つのフォーラムで助けを求めました。 彼は助けを求めたが、彼はそれを少し理解し、彼自身の決定を書いた。

便利なリンク


Source: https://habr.com/ru/post/J92924/


All Articles