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つのフォーラムで助けを求めました。 彼は助けを求めたが、彼はそれを少し理解し、彼自身の決定を書いた。



便利なリンク






All Articles