【问题标题】:Getting "Java Result: -1073741571" on loading library Cryptopp在加载库 Cryptopp 时获取“Java 结果:-1073741571”
【发布时间】:2014-09-06 19:06:17
【问题描述】:

我正在尝试将自定义 c++ dll (使用 jni) 加载到 java,但我有一个 问题: 我的 dll 使用 cryptopp 库,当 java 尝试加载取决于(包括cryptopp),应用程序退出并显示以下消息:

Java 结果: -1073741571

那是什么,我可以在不删除cryptopp的情况下解决这个问题吗?


更新:

如果我评论了文件 zCypto.h 和 zCypro.cpp,并删除了 cryptopp 库的所有使用,它可以正常工作,如果我加载 cryptopp,则会引发错误。 Java 代码:

public static void main(String[] args){
    System.loadLibrary("cryptopp");
    System.loadLibrary("ZCPP_Code64");
}

CPP 源(我在 Visual Studio 2012 中制作 dll):

#include "zCrypto.h"

JNIEXPORT void JNICALL Java_ru_zontwelg_Loader_loadCache 
(JNIEnv *env, jobject jobj)
{

std::fstream stream;
stream.open("C:\\testing_capturing\\enc.zwac", ios_base::binary | ios_base::in);

// Other decode & read stuff here ...

stream.close();
}

标题:

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

#ifndef _Included_ru_zontwelg_Loader
#define _Included_ru_zontwelg_Loader

extern "C" {

    /*
     * Class:     ru_zontwelg_Loader
     * Method:    loadCache
     * Signature: ()V
     */
    JNIEXPORT void JNICALL Java_ru_zontwelg_Loader_loadCache
        (JNIEnv *, jobject);

}

#endif

zCrypto.h:

#ifndef ZontWelg_zCrypto
#define ZontWelg_zCrypto

#include <dll.h>

#include <cstdio>
#include <Windows.h>
#include <iostream>

#include "cryptlib.h"
using CryptoPP::Exception;

#include "hex.h"
using CryptoPP::HexEncoder;
using CryptoPP::HexDecoder;

#include "base64.h"
using CryptoPP::Base64Encoder;
using CryptoPP::Base64Decoder;

#include "filters.h"
using CryptoPP::StringSink;
using CryptoPP::StringSource;
using CryptoPP::StreamTransformationFilter;

#include "sha.h"
#include "rsa.h"
#include "hex.h"
#include "osrng.h"
#include "secblock.h"
#include "modes.h"
#include "aes.h"
using CryptoPP::AES;

//#include "ccm.h"
using CryptoPP::CBC_Mode;

#pragma comment(lib, "cryptlib.lib")
//#pragma comment(lib, "crypt32.lib")
#pragma comment(lib, "cryptopp.lib")

using namespace std;

class zCrypto {
public:
    static string base64(string in);
    static string from_base64(string in);

    static string decrypt(const std::string& str_in);
};

#endif

【问题讨论】:

  • 如果没有看到您的代码,很难判断您做错了什么。你能试着制作一个出现这个问题的最小的程序,然后把它粘贴到这里吗?
  • Eclipse: Java was started but returned exit code -1073741571 的可能重复项。这可能很难搜索,因为 Google 将减号解释为“从结果中删除 1073741571”。试试这个搜索:Java "-1073741571".
  • @Draiget - 我们需要更多细节。这是一个 Android/Ecplise 项目吗?这是一个 Windows 项目吗(可能来自潜在的重复项目)。虚拟机有多少内存?您是否使用javah 从您的 Java 类文件中生成 C/C++ 标头?你是专门调用你的DLL吗?还是您偶尔调用 Crypto++ DLL?
  • @jww - 我尝试在没有“-”的情况下搜索错误,但找不到任何与我的问题相关的内容。这是 NetBeans 中的 Java Application 项目(在 Windows 下编写),dll 是 c++ 动态库(在 Visual Studio 2012 中编写)。对于生成标题我使用javah

标签: java java-native-interface native-code crypto++


【解决方案1】:

这对我来说看起来很奇怪,但无论如何我都不是 JNI 专家:

public static void main(String[] args){
    System.loadLibrary("cryptopp");
    System.loadLibrary("ZCPP_Code64");
}

我希望看到类似的东西(来自我的 Crypto++/Android/JNI 项目之一):

public class PRNG {

    static {
        System.loadLibrary("stlport_shared");
        System.loadLibrary("cryptopp");
        System.loadLibrary("prng");
    }

    private static native int CryptoPP_Reseed(byte[] bytes);

    private static native int CryptoPP_GetBytes(byte[] bytes);

    private static Object lock = new Object();

    // Returns the number of bytes consumed.
    public static int Reseed(byte[] seed) {
        synchronized (lock) {
            return CryptoPP_Reseed(seed);
        }
    }

    // Returns the number of bytes generated.
    public static int GetBytes(byte[] bytes) {
        synchronized (lock) {
            return CryptoPP_GetBytes(bytes);
        }
    }
}

不用担心stlport_shared,因为它是 Android 的东西。


这看起来也很奇怪:

#pragma comment(lib, "cryptlib.lib")
//#pragma comment(lib, "crypt32.lib")
#pragma comment(lib, "cryptopp.lib")

因为您正在调用System.loadLibrary("cryptopp"),这意味着您正在使用 Crypto++ DLL。这也意味着不需要:#pragma comment(lib, "cryptlib.lib")。选择静态链接或动态链接,但不能同时选择两者。

如果您 (1) 构建您的 ZCPP_Code64 DLL,并且 (2) 静态链接到 Crypto++,这可能是最简单的。然后你的静态加载器看起来像:

    static {
        System.loadLibrary("ZCPP_Code64");
    }

如果您选择针对 Crypto++ 的静态链接,那么您可能需要重新构建静态库。那是因为您最终会采用这种配置:

Your DLL -> dynamic linking against the C Runtime
Crypto++ LIB -> static linking against the C Runtime

这会导致一堆重复的符号(C 运行时符号)。你想要的是:

Your DLL -> dynamic linking against the C Runtime
Crypto++ LIB -> dynamic linking against the C Runtime

要修复它,您打开 Cryptlib 项目,并将运行时链接对象从静态更改为动态。请参阅Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment 上的“静态与动态链接”。


这对我来说看起来不错:

JNIEXPORT void JNICALL Java_ru_zontwelg_Loader_loadCache 
(JNIEnv *env, jobject jobj)
{
    ...
}

我不确定...本地库需要位于 Windows 上的什么位置。为此,请查看Java JNI and dependent libraries on Windows


您还必须执行锁定如果多个线程访问相同的底层 Crypto++ 对象。在我的例子中,底层对象是AutoSeededRandomPool:

public class PRNG {

    ...

    // Returns the number of bytes consumed.
    public static int Reseed(byte[] seed) {
        synchronized (lock) {
            return CryptoPP_Reseed(seed);
        }
    }

    // Returns the number of bytes generated.
    public static int GetBytes(byte[] bytes) {
        synchronized (lock) {
            return CryptoPP_GetBytes(bytes);
        }
    }
}

在您的情况下,它可能是 Base64EncoderBase64Decoder

请记住,所有 Crypto++ 类对象都是线程安全的,这意味着它们不会访问全局或共享数据。但是当多个线程(错误)使用同一个对象时,它们是不安全的。


我为 JNI 问题参考的书是The Java Native Interface: Programmer's Guide and Specification


最后,对“答案”感到抱歉。它不是一个真正的答案。相反,它是一个不适合评论块的大评论。

【讨论】:

  • 感谢您提供详细的帖子,但是当 java 加载编译的 64x crypto++ System.load("&lt;full path here&gt;\\cryptopp.dll");System.loadLibrary("cryptopp"); 时出现错误(Java Result: -1073741571
  • 这应该可以工作:System.load("&lt;full path here&gt;\\cryptopp.dll")。所有组件都用于同一平台吗?即,Java 是 64 位的,你的 DLL 是 64 位的,Crypto++ 是 64 位的吗?
  • 我在 windows 目录中复制了 crypto++,我还查看了 Dependency Walker 中的依赖库,他只使用了 KERNEL32.dllADVAPI32.dll。是的,所有库都是 64 位的,包括 JDK。
猜你喜欢
  • 1970-01-01
  • 2019-03-07
  • 2018-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-16
  • 1970-01-01
相关资源
最近更新 更多