4

JAVA プログラム内からサードパーティの .NET DLL (ここから取得) を呼び出そうとしています。ここここを見た後、すべてをコンパイルして実行することができました。しかし、.NET コードを実行すると例外が発生します。

Java ランタイム環境によって致命的なエラーが検出されました

これは、.NET DLL 内から別の .net オブジェクトとメソッドにアクセスしようとしたときにのみ発生します。

JNIEXPORT void JNICALL Java_test_broadcast
(JNIEnv *, jobject)
{
   // Instantiate the MC++ class.
   IManagedWrapper* t = IManagedWrapper::CreateInstance();

   // The actual call is made. 
   t->Broadcast();
}

void ManagedWrapper::Broadcast(std::string message)
{
   //Uncommenting the following line will raise the error
   //IXDBroadcast^ broadcast = XDBroadcast::CreateBroadcast(XDTransportMode::WindowsMessaging);
}

上記のコードにリンクし、必要に応じて動作する .NET DLL を作成することができました。

Java コードから .NET オブジェクトとメソッドを呼び出すにはどうすればよいですか?

4

2 に答える 2

4

コメントで @"Hovercraft Full Of Eels" リンクを最後にたどりました: Calling .Net Dlls from Java code without using regasm.exe

C++\CLI を使用してネイティブ コードとマネージ コードを橋渡ししたところ、見事に機能しました。主な問題は、ブリッジ DLL が JVM で実行され、ロードしようとした DLL が JRE\bin ディレクトリにないことでした。この問題を克服するために、.Net アセンブリを C++/CLI コードから動的にロードしました (これに基づく):

static Assembly^ MyResolveEventHandler( Object^ sender, ResolveEventArgs^ args )
{
    //Retrieve the list of referenced assemblies in an array of AssemblyName.
    Assembly^ MyAssembly;
    Assembly^ objExecutingAssemblies;
    String^ strTempAssmbPath = "";

    objExecutingAssemblies = Assembly::GetExecutingAssembly();
    array<AssemblyName ^>^ arrReferencedAssmbNames = objExecutingAssemblies->GetReferencedAssemblies();

    //Loop through the array of referenced assembly names.
    for each (AssemblyName^ strAssmbName in arrReferencedAssmbNames)
    {
        //Check for the assembly names that have raised the "AssemblyResolve" event.
        if (strAssmbName->FullName->Substring(0, strAssmbName->FullName->IndexOf(",")) == args->Name->Substring(0, args->Name->IndexOf(",")))
        {
            //Build the path of the assembly from where it has to be loaded.                
            strTempAssmbPath = pathBase + args->Name->Substring(0, args->Name->IndexOf(",")) + ".dll";
            break;
        }

    }
    //Load the assembly from the specified path.                    
    MyAssembly = Assembly::LoadFrom(strTempAssmbPath);

    //Return the loaded assembly.
    return MyAssembly;
}
于 2012-04-09T14:38:59.750 に答える
1

これはまさに、Java から .NET へのネイティブ ブリッジがバックグラウンドで行っていることです。

使用する必要がある .NET コードの量と .NET オブジェクトの複雑さ (メソッドの種類、ジェネリックを使用する場合、配列を使用する場合など) に応じて、そのようなブリッジの使用も検討できます。このようなケースをさらに深く掘り下げると、C++/CLI を使用して自分で手動で行うと、次々とさらに多くの制限が発生します。本番環境向けの迅速で信頼性の高いソリューションが必要な場合は、次を確認することをお勧めします。

これらの各ブリッジは、すべてのネイティブ通信をカバーし、.NET を使用して任意の DLL をロードしたり、JAVA アプリケーションで .NET Framework 全体を使用したりするための非常に簡単なインターフェイスを提供します。

必要に応じて、Javanetは、非常に強力で柔軟性のある最も簡単で非常に軽量なものだと思います。優れたサポートと 5 分で作業を完了するための簡単な API を備えた信頼性の高い商用ソリューションを探している場合 (非商用および学術目的の場合は、自由)。強く型付けされたプロキシ クラス ジェネレーターを備えたJNBridgeは、非常に強力であり、特に専用のコネクタが必要な場合は商用利用にも適しています (価格に影響しますが、ニーズによって異なります)。JNI4NETは、非重要で非商用のアプリケーション向けの素晴らしいオープン ソース プロジェクトですが、チェックする価値があります。

このようなブリッジでは、追加の実装を気にする必要はなく、.NET dll をコピーして Java で使用するだけです。ここで見ることができます: http://www.youtube.com/watch?v=n6XfzrHTdK4

于 2013-11-07T21:48:10.747 に答える