当前位置: 首页 > 知识库问答 >
问题:

加载库Cryptopp时获取“Java结果:-1073741571”

国阳
2023-03-14

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

Java结果:-1073741571

那是什么,我可以在不移除密码的情况下修复它吗?

更新:

如果我对文件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

共有1个答案

寿元白
2023-03-14

这对我来说很奇怪,但我并不是JNI专家:

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

我希望看到类似的东西(来自我的一个加密/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\u共享,因为它是Android的东西。

这看起来也很奇怪:

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

因为您正在调用系统。loadLibrary(“cryptopp”),这意味着您正在使用加密DLL。这也意味着不需要这样做:#pragma comment(lib,“cryptlib.lib”)。选择静态链接或动态链接,但不能同时选择两者。

如果(1)构建ZCPP\U Code64的DLL,以及(2)静态链接到Crypto,这可能是最简单的。那么您的静态加载器将如下所示:

java prettyprint-override">    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项目,并将运行时链接对象从静态更改为动态。请参阅编译加密并将其集成到Microsoft Visual C环境中时的“静态链接与动态链接”。

在我看来这没问题:

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

我不确定的是。。。需要在Windows上定位本机库的位置。为此,请看一下Windows上的Java JNI和依赖库。

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

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);
        }
    }
}

在您的情况下,它可能是Base64编码器或Base64解码器。

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

我为JNI问题查阅的书是Java本机接口:程序员指南和规范。

最后,对“答案”感到抱歉。这并不是一个真正的答案。相反,它是一个大的注释,不适合放在注释块中。

 类似资料:
  • 我不熟悉使用CRUD存储库。 我有一个包含三列的数据库表: course_id,姓名,当然 我想得到一份course\u id name的列表,例如, 但是,我不想使用查询,而是使用crud存储库。 我的控制器显示有错误。我可以知道有这个错误吗? 我的控制器 服务 存储库

  • 在过去的一周里,我一直试图在电脑上学习MySQL。我有一个名为用户的数据库和一个名为用户的表,表中有数据。但是我下面有这个PHP代码,它不会得到任何结果,我不知道为什么。

  • 我试图使用Lucene索引进行查询,但得到的结果为空,日志中出现以下错误, 我正在使用RDB DocumentStore,我已经检查了索引和节点是在节点表中创建的。 任何人都可以分享一些关于如何创建Lucene索引的示例代码吗?

  • 如果使用的两个数字和运算符存储在变量中(用户输入),如何返回计算结果。 我正在创建一个简单的计算器,并试图输出“Number”“Operator”“Number2”的答案,根据用户输入的内容,答案可以是任何内容。 当输入这些数字和运算符时,输出返回“5 5=5 5”,我试图返回“5 5=10”。

  • 我在MongoDB中有以下文档: 我正在使用scala代码中的mongo-scala-driver来查询服务器。如何将mapped_column转换为scala字符串变量?我尝试使用以下代码:

  • 应用程序正在启动。获取数据。请稍候...线程“main”java.lang.UnsatisfiedLinkError中出现(约10s)异常:无法加载SWT库。原因:java.library.path中没有swt-cocoa-4236。path中没有swt-cocoa不能加载库:C:\users\andrew.swt\lib\win32\x86_64\swt-cocoa.dll不能加载库:C:\us