簡體   English   中英

JNI C++ DLL -“UnsatisfiedLinkError: %1 不是有效的 Win32 應用程序”

[英]JNI C++ DLL - 'UnsatisfiedLinkError: %1 is not a valid Win32 application'

在深入研究實際代碼之前,我試圖讓 JNI 真正工作,但是在我從 C++ 編譯 DLL 並運行我的 Java 應用程序之后,我得到:

Exception in thread "main" java.lang.UnsatisfiedLinkError: <snip>\workspace\JNI test\native\jnitest.dll: %1 is not a valid Win32 application
    at java.lang.ClassLoader$NativeLibrary.load(Native Method)
    at java.lang.ClassLoader.loadLibrary1(Unknown Source)
    at java.lang.ClassLoader.loadLibrary0(Unknown Source)
    at java.lang.ClassLoader.loadLibrary(Unknown Source)
    at java.lang.Runtime.loadLibrary0(Unknown Source)
    at java.lang.System.loadLibrary(Unknown Source)
    at net.condorcraft110.jnitest.JNITest.main(JNITest.java:11)

在 Google 上搜索了一下,我知道這通常是由於嘗試使用 32 位 JVM 加載 64 位 DLL 引起的。 但是,我的 JVM 是 64 位的,正如sun.arch.data.model等於 64 所證明的sun.arch.data.model

我的生成文件:

CLASSPATH = ../bin

vpath %.class $(CLASSPATH)

all : jnitest.dll

jnitest.dll : jnitest.o
    g++ -m64 -Wl,--add-stdcall-alias -shared -o $@ $<

jnitest.o : jnitest.cpp jnitest.h
    g++ -m64 -I"C:\Program Files\Java\jdk1.7.0_51\include" -I"C:\Program Files\Java\jdk1.7.0_51\include\win32" -c $< -o $@

jnitest.h : net/condorcraft110/jnitest/JNITest.class
    javah -verbose -classpath $(CLASSPATH) -o jnitest.h net.condorcraft110.jnitest.JNITest

clean :
    rm jnitest.h jnitest.o jnitest.dll

JNITest.java:

package net.condorcraft110.jnitest;

public class JNITest
{
    private static native void test();

    public static void main(String[] args)
    {
        System.out.println("sun.arch.data.model = " + System.getProperty("sun.arch.data.model"));

        System.loadLibrary("jnitest");

        test();
    }
}

由 javah 生成的 jnitest.h:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class net_condorcraft110_jnitest_JNITest */

#ifndef _Included_net_condorcraft110_jnitest_JNITest
#define _Included_net_condorcraft110_jnitest_JNITest
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     net_condorcraft110_jnitest_JNITest
 * Method:    loadPlugins
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_net_condorcraft110_jnitest_JNITest_test
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

jnitest.cpp:

using namespace std;

#include <jni.h>
#include <iostream>
#include "jnitest.h"

extern "C" JNIEXPORT void JNICALL Java_net_condorcraft110_jnitest_JNITest_test(JNIEnv *env, jclass clazz)
{
    cout << "jni test successful" << endl;
}

有誰知道為什么這不起作用?

編輯: java.library.path絕對指向native ,如在 Eclipse 運行配置中設置的那樣。
編輯 2:如果我用 VS2013 編譯 DLL,它就可以工作,但如果我能幫上忙,我真的不想將我的項目綁定到 Visual Studio。

對我來說,問題是我新添加的DLL依賴於我不知道的其他DLL。 Windows有幫助地在我的路徑中找到了一個32位版本,但無法加載它,因為我的應用程序是64位。

我使用Dependency Walker (有32位和64位版本,以及Itanium ...)和Process Monitor來調試它。 它的長短是確保你的DLL所引入的每個DLL也是64位,你會更開心。

需要注意的一件事是,如果Windows找到一個正確名稱的32位DLL,它會嘗試加載它,而在Process Monitor中,它看起來就像是在成功讀取它。 確保繼續向下滾動!! 您可能會發現系統丟棄此DLL並繼續搜索64位版本的路徑。

更新:
另外兩件事要注意:

1)舊的Dependency Walker可能看起來像它加載的DLL不匹配,例如它可能首先找到32位匹配,當你真的想要一個64位DLL,並告訴你有CPU類型不匹配。 剛剛獲得新版本,這個問題就消失了。 感謝https://stackoverflow.com/a/22384936/309502獲取此信息。

2)加載DLL時,順序很重要。 我沒有意識到我正在以錯誤的順序裝載其中兩個,並且無法弄清楚它為什么不起作用。 檢查您是否先加載先決條件。 :-)

我也遇到了同樣的問題。 在我的情況下的問題是我的dll采取了一些64位依賴的DLL。 我打開我的jni dll進入依賴walker,在那里我找到了64位dll。 我用32位替換它。 我的問題得到了解決。

我最初得到Can't find dependent libraries錯誤,解決了我在路徑中添加了DLL的問題。 但這導致我錯誤%1 is not a valid Win32 application at java 為了解決這一切,使靜態構建為我工作,編譯: g++ -static 它在構建本身中添加了依賴庫。

我通過將這些 .dll 文件的列表從 Win64_x64 復制到應用程序的 bin/main 目錄來解決我的問題,並且應用程序運行成功:

NBiometricClient.dll
NBiometrics.dll
NCore.dll
NDevices.dll
NLicensing.dll
NMedia.dll
NMediaProc.dll
NMMAbisClient.dll 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM