13

WindowsXPのアプレットから呼び出されるC++でいくつかのJNIコードを書いています。アプレットを正常に実行し、JNIライブラリをロードして呼び出すことができました。さらに、他のDLLの関数を呼び出すこともできました。すべてのDLLが含まれるディレクトリを含めるようにPATHシステム環境変数を設定することで、これを機能させることができました。

したがって、問題は、新しい外部DLLを使用する別の呼び出しを追加すると、ライブラリをロードするときに突然UnsatisfiedLinkErrorがスローされることです。メッセージは次のとおりです。'指定されたプロシージャが見つかりませんでした'。依存DLLを削除して、依存DLLが見つからないという別のメッセージを受け取ることができるため、これは依存DLLがない場合の問題ではないようです。私がオンラインで見つけたものから、このメッセージはネイティブJava関数の実装がDLLにないことを意味しているように見えますが、この余分なコードがなくても正常に動作するのは奇妙です。

誰かがこれを引き起こしている可能性があることを知っていますか?UnsatisifedLinkErrorに対して「指定されたプロシージャが見つかりませんでした」というメッセージを表示できるのはどのようなものですか?

4

6 に答える 6

18

私は問題を理解しました。これはすごいことでした。UnsatisfiedLinkError の「指定されたプロシージャが見つかりませんでした」というメッセージは、ルート dll または依存 dll内の関数が見つからなかったことを示します。JNI の状況でこれが発生する原因として最も可能性が高いのは、ネイティブ JNI 関数が正しくエクスポートされていないことです。しかし、依存する DLL がロードされていて、その DLL にその親が必要とする機能がない場合に、これが明らかに発生する可能性があります。

例として、input.dll という名前のライブラリがあります。DLL の検索順序は、常にアプリケーション ディレクトリを最初に検索し、PATH ディレクトリを最後に検索することです。以前は、input.dll と同じディレクトリから常に実行可能ファイルを実行していました。ただし、Windows システム ディレクトリ (DLL 検索順序の中間) に別の input.dll があります。したがって、これを Java アプレットから実行する場合、上記のコードをアプレットに含めると、input.dll が読み込まれ、システム ディレクトリから input.dll が読み込まれます。私たちのコードは、input.dll に存在しない特定の関数を想定しているため (別の DLL であるため)、ロードは失敗し、プロシージャが見つからないというエラー メッセージが表示されます。JNI 関数が間違ってエクスポートされたからではなく、間違った依存 DLL がロードされ、それがロードされなかったからです。

于 2008-10-07T21:47:12.510 に答える
2

DLL が (C ではなく) C++ を使用してビルドされた可能性があります。プロシージャで extern を実行するように注意しない限り、これが考えられる理由の 1 つです。

DLL からすべての関数をエクスポートしてみてください。リストに関数が含まれていれば、問題ありません。

于 2008-10-01T23:10:00.813 に答える
0

通常、他のライブラリにリンクする場合は、関連する.libファイルにリンクする必要があります。必要なすべてのlibファイルを参照しているわけではないようです。リンクされていないものを確認し、そのlibがリンカーのリストに追加されていることを確認してください。

于 2008-10-01T21:31:13.033 に答える
0

JNI のマニュアルとサンプルですべてのプログラミングの問題を解決しても、同じ手順エラーが発生する場合は、おそらくパス変数に問題がある可能性があります。以下の手順を実行して、再度実行します。

  1. JAVA_HOME変数をJDKフォルダーに設定してください(JREにはjniヘッダーが含まれていないため、JREではありません)例: 環境変数設定パネルで、var:JAVA_HOME val:C:\Program Files\Java\jdk1.7.0_11を定義します
  2. %JAVA_HOME%\binをパス変数に追加します

これらの手順を実行すると、アプリケーションは jni プロシージャ名と JNI.dll へのリンクを正しい方法で見つけることができます。したがって、この欠落した手順エラーが再び発生しないことを願っています。

于 2015-01-15T12:21:45.380 に答える
0

標準の JNI 手順を使用して新しい外部 DLL を作成しましたか? つまり、javahなどを使用していますか?もしそうなら、私は何が間違っているのか分かりません。

そうでない場合、呼び出そうとしているプロシージャはエクスポートされていません (anjanb で述べられているように)。私は、関数をエクスポートする 2 つの方法を認識しています。個別のエクスポート リストと、特定の関数を __declspec(dllexport) でマークする方法です。

Can't access variable in C++ DLL from a C appには、DLL のトピックに関する情報がもう少しあります。

于 2008-10-03T01:03:29.147 に答える
0

C++ コードをデバッグ モードでコンパイルします。次に、DebugBreak(); を挿入します。デバッグを開始したいステートメント。Java コードを実行します。DebugBreak() ステートメントが検出されると、[デバッグ] ボタンが表示されたポップアップが表示されます。クリックして。Dev Studio が開き、マシン コードでプログラムが表示されます。デバッガーを 2 回ステップ オーバーすると、ソース コードをステップ オーバーできるはずです。

于 2009-10-20T12:30:17.073 に答える