【问题标题】:JNI C++ DLL - 'UnsatisfiedLinkError: %1 is not a valid Win32 application'JNI C++ DLL - 'UnsatisfiedLinkError: %1 不是有效的 Win32 应用程序'
【发布时间】:2015-02-09 19:47:37
【问题描述】:

在我开始使用实际代码之前,我试图让 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 证明了这一点。

我的生成文件:

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:如果我编译,DLL 可以工作VS2013,但如果我能提供帮助,我真的不想将我的项目绑定到 Visual Studio。

【问题讨论】:

  • 你有没有发现这里的问题?我遇到了同样的问题,使用 64 位 gcc 和 cygwin。
  • @Philip 我解决了这个问题。看看你的问题是否和我的类似。 :-)

标签: java c++ windows dll java-native-interface


【解决方案1】:

对我来说,问题在于我新添加的 DLL 依赖于我不知道的其他 DLL。 Windows 在我的路径中找到了一个 32 位版本,但由于我的应用程序是 64 位,因此无法加载它。

我使用Dependency Walker(有 32 位和 64 位版本,以及 Itanium...)和Process Monitor 来调试它。总而言之,确保你的 DLL 引入的每个 DLL 也是 64 位的,这样你会更开心。

需要注意的一点是,如果 Windows 找到了一个名称正确的 32 位 DLL,它会尝试加载它,并且在进程监视器中它看起来像是在成功读取它。确保继续向下滚动!!您可能会发现系统丢弃了这个 DLL 并继续搜索 64 位版本的路径。

更新:
另外两件事需要注意:

1) 旧的 Dependency Walker 看起来可能与其加载的 DLL 不匹配,例如当你真的想要一个 64 位 DLL 时,它可能会首先找到一个 32 位匹配,并告诉你 CPU 类型不匹配。只需获取新版本,此问题就会消失。感谢 https://stackoverflow.com/a/22384936/309502 提供此信息。

2) 加载 DLL 时顺序很重要。我没有意识到我以错误的顺序加载其中两个,并且无法弄清楚为什么它不起作用。检查您是否首先加载了先决条件。 :-)

【讨论】:

  • 当我回到我的开发机器时我会试试这个,但感谢你回答这么久的问题!
  • 有趣!我设法通过完全切换到 mingw 而不是 cygwin 来“解决”我的问题,但最好测试一下。我的理解是 cygwin 编译的应用程序需要加载特定于 cygwin 的 DLL,并且禁用此功能的 gcc 选项被排除在版本 4+ 之外,并且仍然没有被添加回来。我想这个问题可能解决了 32 位 cygwin DLL 而不是 64。
  • Dependency Walker 帮了大忙!感谢您的提示!
【解决方案2】:

我最初收到Can't find dependent libraries 错误,为了解决这个问题,我在路径中添加了 DLL。但这导致我出现错误%1 is not a valid Win32 application at java。为了解决这一切,制作一个静态构建对我有用,它编译为:g++ -static。它在构建本身中添加依赖库。

【讨论】:

    【解决方案3】:

    我也遇到了同样的问题。 我的问题是我的 dll 占用了一些 64 位相关的 dll。 我将我的 jni dll 打开到依赖 walker 中,在那里我找到了 64 位 dll。我用32位替换它。 我的问题得到了解决。

    【讨论】:

      【解决方案4】:

      我通过将这些 .dll 文件的列表从 Win64_x64 复制到应用程序的 bin/main 目录中解决了我的问题,应用程序运行成功:

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

      【讨论】:

        猜你喜欢
        • 2019-08-26
        • 1970-01-01
        • 2012-09-08
        • 2012-03-05
        • 1970-01-01
        • 2014-01-02
        • 2013-01-15
        • 2012-01-25
        • 2019-01-17
        相关资源
        最近更新 更多