1

私はJNIに問題があります、再び...

今回は私のコードが機能します...しかし...すべてのPCで正しいわけではありません。

私は持っている:

  1. Jar ファイル -> 私のプログラム
  2. dll ファイル -> ネイティブ メソッドを使用
  3. 別のdllファイル->別の機能を使用。

私のPCでは、このファイルはすべて1つのフォルダーにあります。

ファイルコード (.java):

// loading library
    try {
        Runtime.getRuntime().loadLibrary("E140tests");
        setText("Library E140tests.dll was loaded correctly.");
    } catch (UnsatisfiedLinkError ex) {
        // try load with absolute path
        setText("Error: E140tests.dll wasn't loaded!");
        setErrorFlag(true);
    }

E140tests.dll -> 2 番目のファイル (MSVS でコンパイル)

#include "jni.h"
#include "jni_md.h"
#include "Lusbapi.h"
#include "LusbapiTypes.h"
#include "JNITEST2.h"

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Class:     JNITEST2
 * Method:    ADCinit
 * Signature: (LJNITEST2;)V
 */
JNIEXPORT void JNICALL Java_JNITEST2_ADCinit
  (JNIEnv* env, jobject, jobject obj) {
  ...

lusbapi.dll -> 3 番目のファイルで、別の機能があります。

#ifndef __LusbapiH__
#define __LusbapiH__

// --------------------------------------------------------------------------
// ---------------------------- COMMON PART ---------------------------------
// --------------------------------------------------------------------------
#include <windows.h>
#include "LusbapiTypes.h"

ファイルをsystem32に投げると、すべてうまくいきます。

しかし。別の PC (XP、7) で私のコードが動作しません! 関係ありません: ファイル (+dll) が 1 つのフォルダーにある場合、または dll ファイルが system32 にある場合 -> コードはそれらを見つけることができません。

その問題はランタイム ライブラリ (MSVS) にあると思いましたが、それらをインストールしても何も変わっていません...

(私のPCにはIntelijIDEA、MSVS、jdk7.xxがあります->すべて動作します。別のPC(MSVSがインストールされている)でprogをテストしました->すべて動作しました。しかし、別のPCでは-> dllが見つかりませんでした(およびランタイムライブラリがインストールされています)それも))。

私は助けを待っています)

4

3 に答える 3

2

残念ながら、.DLL をコンパイルすると、アーキテクチャが一致するシステムとしか互換性がありません。

別名: 32 ビット .DLL は 32 ビット マシンで動作します。64 ビットでも同じことが言えます。これを回避するための戦術があります (Visual Studio のライセンスを購入すると、これを可能にするツールが提供され、プラットフォーム固有の .dll が生成されます)、適切な .DLL をプログラムのバージョンに関係なくバンドルする必要があります。テスト中です。そのため、ほとんどの場合、Web サイトで 32 ビットまたは 64 ビットのマシンを使用しているかどうかを尋ねられます。

これはまた、Java が優れている主な理由の 1 つです。なぜなら、それは「プラットフォームに依存しない」からです (私はこの用語を大まかに使用しています。これは、他の要因がこれに影響を与えて真実でなくなる可能性があるためです)。

いずれにせよ、JNI 呼び出しを追加するとすぐに、大量の依存関係が追加され、ソフトウェアの配布が少し難しくなります。

于 2013-11-01T14:54:26.117 に答える
0

両方のアーキテクチャで DLL をコンパイルする必要があります。コンパイルには、64 ビット システムを使用し、これらのコマンドを使用してコンパイルできます。

64 ビット (GCC) の場合

gcc -o E140Tests64.dll -shared -IC:\....\include sourcefile.c

32 ビット (GCC) の場合

gcc -o E140Tests.dll -shared -IC:\....\include sourcefile.c

お役に立てれば。

于 2013-11-01T15:03:19.293 に答える
0

アプリケーションを配布する場合は、DLL の 32 ビット バージョンと 64 ビット バージョンの両方をビルドする必要があります。次に、次の手法を使用して、顧客の JVM アーキテクチャに関係なく、適切な DLL をロードします。生成された出力ファイルに 32 または 64 (MyJniDLL32.dll & MyJniDLL64.dll) を追加します。

String archDataModel = System.getProperty("sun.arch.data.model");
System.loadLibrary(libraryName+archDataModel);

DLL のアーキテクチャ (32 対 64) は、OS アーキテクチャではなく、JVM の各アーキテクチャ (32 対 64) と一致する必要があります。64 ビット OS で 32 ビット JVM を実行している場合、Java コードは 32 ビット DLL にアクセスできる必要があります。

于 2013-11-07T14:29:52.380 に答える