サード パーティの .NET アセンブリと大規模な Java アプリケーションがあります。.NET クラス ライブラリが提供するメソッドを Java アプリケーションから呼び出す必要があります。アセンブリは COM 対応ではありません。私はネットを検索しましたが、これまでのところ、次のものがあります。
C# コード (cslib.cs):
using System;
namespace CSLib
{
public class CSClass
{
public static void SayHi()
{
System.Console.WriteLine("Hi");
}
}
}
(.net 3.5 を使用しますが、2.0 を使用した場合も同じことが起こります):
csc /target:library cslib.cs
C++ コード (clib.cpp):
#include <jni.h>
#using <CSLib.dll>
using namespace CSLib;
extern "C" _declspec(dllexport) void Java_CallCS_callCS(JNIEnv* env, jclass cls) {
CSLib::CSClass::SayHi();
}
(VC 2008 ツールを使用しますが、2003 ツールを使用した場合も同じことが起こります):
cl /clr /LD clib.cpp
mt -manifest clib.dll.manifest -outputresource:clib.dll;2
Java コード (CallCS.java):
class CallCS {
static {
System.loadLibrary("clib");
}
private static native void callCS();
public static void main(String[] args) {
callCS();
}
}
Java クラスを実行しようとすると、メソッドの呼び出し中に Java VM がクラッシュします (ライブラリをロードできます)。
# # Java ランタイム環境によって予期しないエラーが検出されました: # # 内部エラー (0xe0434f4d)、pid=3144、tid=3484 # # Java VM: Java HotSpot(TM) クライアント VM (10.0-b19 混合モード、windows-x86 を共有) # 問題のあるフレーム: # C [kernel32.dll+0x22366] # ... Java フレーム: (J=コンパイル済み Java コード、j=解釈済み、Vv=VM コード) j CallCS.callCS()V+0 j CallCS.main([Ljava/lang/String;)V+0 v ~StubRoutines::call_stub
ただし、clib.dll をロードし、エクスポートされた関数 Java_CallCS_callCS を呼び出す単純な cpp アプリケーションを作成すれば、すべて問題ありません。x86 環境と x64 環境の両方でこれを試しましたが、結果は同じです。他のバージョンの Java は試していませんが、1.5.0 で実行するにはコードが必要です。
さらに、システム メソッドのみを呼び出すように clib.cpp を変更すると、Java からでもすべて正常に動作します。
#include <jni.h>
#using <mscorlib.dll>
using namespace System;
extern "C" _declspec(dllexport) void Java_CallCS_callCS(JNIEnv* env, jclass cls) {
System::Console::WriteLine("It works");
}
まとめると:
- Java -> clib.dll -> mscorlib.dll からシステム メソッドを呼び出すことができます。
- CPPApp -> clib.dll -> cslib.dll から任意のメソッドを呼び出すことができます
- Java からメソッドを呼び出すことができません -> clib.dll -> cslib.dll
上記の 1. を使用する回避策を認識しています - リフレクションを使用してアセンブリをロードし、システム コールのみを使用して目的のメソッドを呼び出すことができますが、コードが乱雑になり、より良い解決策を期待しています。
リフレクション方式を使用する dotnetfromjava プロジェクトについては知っていますが、必要以上に複雑にすることは避けたいと考えています。ただし、他に方法がない場合は、このようなものを使用します。
私は ikvm.net も調べましたが、私の理解では、独自の JVM (C# で記述) を使用して魔法を実行しています。ただし、Java アプリケーション全体をその VM の下で実行することは、私にとって選択肢ではありません。
ありがとう。