JNA,Mapping和指针引用

问题描述 投票:1回答:1

我需要在我的Java应用程序中使用DLL。 DLL正在导出一些函数,作者称之为“Direct DLL API”。我正在尝试在java中定义以下函数声明:

int XcCompress( HXCEEDCMP hComp, const BYTE* pcSource, DWORD dwSourceSize, BYTE** ppcCompressed, DWORD* pdwCompressedSize, BOOL bEndOfData );

在我的扩展库的界面中我声明如下:

int XcCompress(WString hComp, Pointer pcSource, int dwSourceSize, Pointer[] ppcCompressed, IntByReference pdwCompressedSize, boolean bEndOfData);

问题是每次我收到错误:

线程“main”中的异常java.lang.Error:无效的内存访问

所以基本上我已经陷入了困境。

HXCEEDCMP hComp - 假设存储处理程序到函数,并作为初始DLL DLL /破坏DLL函数的WString工作正常,所以我保持这样。

标题引用“creature”是:

typedef HXCEEDCMP ( XCD_WINAPI *LPFNXCCREATEXCEEDCOMPRESSIONW )( const WCHAR* );

const BYTE* pcSource - 是压缩的源数据,在我的代码中我以这种方式实例化它:

private static Pointer setByteArrayPointer(String dataToCompress) {
  Pointer pointer = new Memory(1024);
  pointer.write(0, dataToCompress.getBytes(), 0, 
  dataToCompress.getBytes().length);

  return pointer;
}

DWORD dwSourceSize - 为此我以这种方式保留内存大小:

String testData = "ABCDABCDABCDAAD";
Pointer source = setByteArrayPointer(testData);

(int) ((Memory)source).size()

BYTE** ppcCompressed - 函数应在工作完成后填充ppcCompressed参考。我假设我犯了一个错误,通过这样做:

Pointer[] compressed = {new Pointer(1024), new Pointer(1024)};

DWORD* pdwCompressedSize - 由压缩数据的函数大小返回。我用这种方式映射它:

IntByReference intByReference = new IntByReference();

不确定这是不是好主意...

BOOL bEndOfData - 我需要将其设置为true。

所以最后我的方法调用,返回一个错误,如下所示:

xceedApiDll.XcCompress(handle, source, (int) ((Memory)source).size(), compressed, intByReference, true);

任何帮助将不胜感激。谢谢。

java api pointers dll jna
1个回答
1
投票

我想我解决了这个问题(感谢评论家伙)。也许对于使用此库的人来说,它会很有用:

最后,主要问题是处理程序声明和ppcCompressed值。

我使用以下解决方案对我来说很好:

java接口里面的方法声明:

int XcCompress(Pointer hComp, byte[] pcSource, int dwSourceSize, PointerByReference ppcCompressed, IntByReference pdwCompressedSize, int bEndOfData);
int XcUncompress(Pointer hComp, byte[] pcSource, int dwSourceSize, PointerByReference ppcUncompressed, IntByReference pdwUncompressedSize, int bEndOfdata);

用法:

private static final XceedFunctions XCEED_DLL_API;

static {
    XCEED_DLL_API = Native.load("XceedZipX64", XceedFunctions.class);
}

private static final String TEST_DATA = "abcabcddd";

//Data pointers
private static Pointer compHandle;
private static byte[]  baSource = TEST_DATA.getBytes();
private static PointerByReference pbrCompressed = new PointerByReference();
private static PointerByReference pbrUncompressed = new PointerByReference();
private static IntByReference ibrCompressedSize = new IntByReference();
private static IntByReference ibrUncompressedSize = new IntByReference();

public static void main(String[] args) {
    try {
        boolean isSuccessfulInit = XCEED_DLL_API.XceedZipInitDLL();
        if(isSuccessfulInit) {
            compHandle = XCEED_DLL_API.XcCreateXceedCompressionW(new WString("YOUR_LICENCE_KEY_HERE"));
            int compressionResult = XCEED_DLL_API.XcCompress(compHandle, baSource, baSource.length, pbrCompressed, ibrCompressedSize, 1);
            byte[] compressed = getDataFromPbr(pbrCompressed, ibrCompressedSize);
            System.out.println("Compression result: " + compressionResult + " Data: " + new String(compressed));
            int decompressionResult = XCEED_DLL_API.XcUncompress(compHandle, compressed, compressed.length, pbrUncompressed, ibrUncompressedSize, 1);
            byte[] uncompressed = getDataFromPbr(pbrUncompressed, ibrUncompressedSize);
            System.out.println("Decompression result: " + decompressionResult + " Data: " + new String(uncompressed));
        }
    } finally {
        System.out.println("Free memory and shutdown");
        if(compHandle != null) {
            XCEED_DLL_API.XcDestroyXceedCompression(compHandle);
        }
        XCEED_DLL_API.XceedZipShutdownDLL();
    }
}

private static byte[] getDataFromPbr(PointerByReference pbr, IntByReference ibr) {
    return pbr.getValue().getByteArray(0, ibr.getValue());
}

示例输出:

压缩结果:0数据:KLJNLJNII yK

减压结果:0数据:abcabcddd

可用内存和关机

© www.soinside.com 2019 - 2024. All rights reserved.