Получение «Java Result: -1073741571» при загрузке библиотеки Cryptopp

1

Я пытаюсь загрузить пользовательскую c++ dll (используя jni) в java, но у меня есть проблема: моя dll с использованием библиотеки cryptopp, и когда java пытается загрузить в зависимости (включая криптопп), приложение завершает работу с сообщением:

Java Результат: -1073741571

Что это, я могу исправить это, не удаляя криптопп?


Обновить:

Если я прокомментировал файлы zCypto.h и zCypro.cpp и удалил все использование библиотеки cryptopp, он работает без каких-либо ошибок, возникла ошибка при загрузке криптоппа. Код Java:

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

CPP Source (я делаю dll в Visual Studio 2012):

#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
  • 0
    Трудно сказать, что ты делаешь неправильно, не видя свой код. Можете ли вы попробовать создать наименьшую возможную программу, которая демонстрирует эту проблему, и вставить ее здесь?
  • 0
    Возможная копия Eclipse: Java была запущена, но возвращен код выхода -1073741571 . Это может быть сложно найти, потому что Google интерпретирует знак минус, чтобы означать «удалить 1073741571 из результатов». Попробуйте этот поиск: Java "-1073741571" .
Показать ещё 2 комментария
Теги:
jni
crypto++
native-code

1 ответ

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"), это означает, что вы используете DLL Crypto++. Это также означает, что это не нужно: #pragma comment(lib, "cryptlib.lib"). Выберите статическое связывание или динамическое связывание, но не оба.

Вероятно, было бы проще, если бы вы (1) построили вашу DLL ZCPP_Code64 и (2) статически связаны с Crypto++. Тогда ваш статический загрузчик будет выглядеть так:

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

Если вы выберете статическое соединение с Crypto++, вам, вероятно, придется перестроить статический lib. Это потому, что вы попадете в эту конфигурацию:

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

Это вызовет кучу повторяющихся символов (C Runtime symbols). Вы хотите:

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

Чтобы исправить это, вы открываете проект Cryptlib и изменяете объект привязки Runtime от статического до динамического. См. "Статическое сравнение с динамическим связыванием" при компиляции и интеграции Crypto++ в среду Microsoft Visual C++.


Это выглядит хорошо для меня:

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

Что я не уверен... где родные библиотеки должны быть расположены в Windows. Для этого взгляните на Java JNI и зависимые библиотеки в 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);
        }
    }
}

В вашем случае это может быть Base64Encoder или Base64Decoder.

Помните, что все объекты класса Crypto++ являются потокобезопасными, потому что они не имеют доступа к глобальным или общим данным. Но они небезопасны, когда несколько потоков (mis) используют один и тот же объект.


Книга, в которой я консультируюсь по вопросам JNI, - это интерфейс Java Native Interface: Руководство программиста и спецификация.


Наконец, жаль насчет "ответа". Это не ответ. Скорее, это большой комментарий, который не вписывался бы в блок комментариев.

  • 0
    Спасибо за подробный пост, но я получаю сообщение об ошибке ( Java Result: -1073741571 ), когда загрузка Java скомпилирована 64x crypto ++ System.load("<full path here>\\cryptopp.dll"); или System.loadLibrary("cryptopp");
  • 0
    @Draiget - Вы взглянули на Java JNI и зависимые библиотеки в Windows ?
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню