JNA:内存访问无效

时间:2017-10-04 03:51:56

标签: java jna

我编写了一个小型C库,用于从DLL中提取信息(一个密钥)。

GetKey.h

#pragma once

#include <stdint.h>

#define getKey(x) getKeyL(x)
#define getKey(x,y) getKeyP(x,y)

void __declspec(dllexport) getKeyP(char *path, uint8_t key[]);
void __declspec(dllexport) getKeyL(uint8_t key[]);

GetKey.c

#include "getkey.h"

#include <stdio.h>
#include <string.h>
#include <windows.h>

void __declspec(dllexport) getKeyP(char *path, uint8_t key[])
{
    int lib = LoadLibraryA((path != NULL) ? path : "myLib");
    ((void(*)(void))(lib + 0x1340))();
    lib += 0x14020;

    for (int i = 0; i < 8; ++i)
    {
        key[i] = *(uint8_t*)(lib + (i << 4));
    }

    FreeLibrary(lib);
}

void __declspec(dllexport) getKeyL(uint8_t key[])
{
    getKeyP(NULL, key);
}

我的Java绑定看起来像这样:

public class GetKey
{
    private static final GetKeyBinding INSTANCE;

    static
    {
        System.setProperty("jna.library.path", "lib/dll/");

        GetKeyBinding lib;

        try
        {
            lib = Native.loadLibrary("x86_64/GetKey.dll", GetKeyBinding.class);
        } 
        catch (UnsatisfiedLinkError e)
        {
            try
            {
                lib = Native.loadLibrary("i386/GetKey.dll", GetKeyBinding.class);
            } 
            catch (UnsatisfiedLinkError f)
            {
                System.err.println("Failed to load library");
                lib = null;
            }
        }

        INSTANCE = lib;
    }

    public static void getKey(byte[] path, byte[] key)
    {
        INSTANCE.getKeyP(path, key);
    }

    public static void getKey(byte[] key)
    {
        INSTANCE.getKeyL(key);
    }

    private static interface GetKeyBinding extends Library
    {
        void getKeyP(byte[] path, byte[] key);
        void getKeyL(byte[] key);
    }
}

每当我调用getKeyPgetKeyL时,我都会抛出异常 我尝试将参数类型从byte[]更改为Pointer以及ByteBuffer,我还尝试extend StdCallLibrary #include <stdio.h> #include "GetKey.h" int main() { uint8_t key[8]; getKeyP(NULL, key); for (int i = 0; i < 8; ++i) { printf("%02X ", key[i]); } getchar(); return 0; } (这对我来说最初没有多大意义,但它可以永远不会受到影响,是吗?可以吗?)仍然有例外......我知道代码有效,因为我写了一个小测试应用程序:

byte[] key = new byte[8];
GetKey.getKey(key);

打印到控制台的确是我期待它打印的内容...... 任何帮助都很高兴!

修改
我这样从Java调用我的函数:

...
elif request.is_ajax():
    product_id = request.POST.get('value')
    if product_id:
        product_info = Product.objects.get(id=product_id)
        new_invoice_product = InvoiceProduct.objects.create(invoice_product_set=product_info)
        invoice.attached_products.add(new_invoice_product)
        context['attached_products'] = invoice.attached_products.all()
...

return render(request, 'inventory/invoice_create.html', context)

1 个答案:

答案 0 :(得分:0)

将调试器附加到我的DLL并进行调试之后,我发现异常的原因是&#34;垃圾&#34;在预期的字符串之后传递的字符。 我通过更改我的Java代码来解决这个问题:

public static void getKey(String path, byte[] key)
{
    INSTANCE.getKeyP((path + '\0').getBytes(), key);
}

现在它按预期工作( - :