Java で DLL ファイルのメソッドにアクセスしようとしています。
ComfyJを使用して DLL ファイルのラッパーを作成したいと考えていました。ComfyJ にはこのためのウィザードがありますが、DLL ファイルを選択すると、この種の DLL ファイルは使用できないと表示されます。
というわけで、次にJNIWrapperウィザードを使ってみましたが、.h
ファイルが必要です。.h
問題は、この DLL 用のファイルがないことです。
(私はこれら両方のツールの商用ライセンスを持っています)。
.h
特定の DLL ファイルのファイルをエクスポートまたは作成する方法がないことに少し驚いています。インターネットを検索しましたが、これを実行できるツールが見つかりませんでした。これにより、DLL ファイルには含まれていないが、このファイルを作成するために必要な情報がまだ不足しているように感じ.h
ます。
次に、すべてのメソッド名、パラメーター、および戻り値の型を実際に知っています。これは、WinApiOverrideツールがそれらを一覧表示できるためです。アプリケーションの実行中に、この DLL ファイルの関数/メソッドに渡されるパラメーターを確認することもできます。
Foo.dll|bool __cdecl ?FooAddBar@@YA_NHHH@Z(int,int,int)
ですから、必要な情報はすべて揃っているという印象を受けました。深く掘り下げる前に...私の質問:メモ帳を使用して手動でこのファイルを作成することは可能だと思いますか?.h
法律上の注意: この DLL ファイルは、プリインストールされた DLL ではありません。これは、有効な商用ライセンスを所有している商用アプリケーションの一部です。同社は、私が個人的な目的でのみ使用する限り、DLL ファイルを自由に使用できると言っています。
編集:
また、jniwrapper コードを自分で作成しようとしました。結果は次のようになります。
Library lib = new Library("foo", Function.CDECL_CALLING_CONVENTION);
lib.load();
// works fine.
Function f = lib.getFunction("?FooAddBar@@YA_NHHH@Z");
// doesn't work.
f.invoke(null, new Int(), new Int(), new Int());
結果は派手な例外です:
Exception c0000005, at 157694FA
Access violation: attempting to read memory at address 00000078
Native function stack data: 0,0,0,0,b0dcbfe6,800fdc5,65637845,6f697470,3063206e,30303030,202c3530,31207461,39363735,a414634,65636341,76207373
Exception in thread "main" com.jniwrapper.FunctionExecutionException: c0000005
at com.jniwrapper.Function.invokeCFunc(Native Method)
at com.jniwrapper.FunctionCall.a(SourceFile:127)
at com.jniwrapper.FunctionCall.call(SourceFile:35)
at com.jniwrapper.Function.invoke(SourceFile:188)
at com.jniwrapper.Function.invoke(SourceFile:239)
その奇妙なメソッド名は正しい形のようです。メソッド名が奇妙に見えます。これは、C++ が dll ファイル内のファイル名を「エンコード」するためであることがわかりました。?FooAddBar@@YA_NHHH@Z
実際にはありbool FooAddBar (int, int, int)
ます。
それにもかかわらず、JNIWrapper はエンコードされた名前を好むようです。短い名前"FooAddBar"
やその他のものを試してみると、メソッドが見つからないため、すでに例外が発生しているためです。一方、エンコードされたメソッド名 (つまり"?FooAddBar@@YA_NHHH@Z"
) を使用すると、メソッドが見つかり、正しいメソッドであることが証明されます。
ただし、呼び出し中に、問題が発生します。だから、私は間違ったパラメータか何かを使用していると推測しています。明らかに、私は何か間違ったことをしており、JniWrapper ウィザードがこれを修正する正しいラッパーを作成できることを望んでいます。(ただし、その場合、.h
ファイルが必要です)。