Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JNA、映射和指针引用_Java_Api_Pointers_Dll_Jna - Fatal编程技术网

Java JNA、映射和指针引用

Java JNA、映射和指针引用,java,api,pointers,dll,jna,Java,Api,Pointers,Dll,Jna,我需要在Java应用程序中使用DLL。DLL正在导出一些函数集,作者称之为“直接DLL API”。我试图用java定义以下函数声明的等价物: int XcCompress( HXCEEDCMP hComp, const BYTE* pcSource, DWORD dwSourceSize, BYTE** ppcCompressed, DWORD* pdwCompressedSize, BOOL bEndOfData ); 在扩展库的接口中,我声明如下: int XcCompress(WStri

我需要在Java应用程序中使用DLL。DLL正在导出一些函数集,作者称之为“直接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中出现异常。错误:内存访问无效

所以基本上我被困在这一点上

HXCEEDCMP-hComp
-假定将处理程序存储到函数中,并作为初始化DLL/销毁DLL函数的WString正常工作,因此我将其保持为这样

标题参考“生物”是:

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;
}
String testData = "ABCDABCDABCDAAD";
Pointer source = setByteArrayPointer(testData);

(int) ((Memory)source).size()
Pointer[] compressed = {new Pointer(1024), new Pointer(1024)};
IntByReference intByReference = new IntByReference();
DWORD dwSourceSize
-对于此im,通过以下方式获取保留内存大小:

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

  return pointer;
}
String testData = "ABCDABCDABCDAAD";
Pointer source = setByteArrayPointer(testData);

(int) ((Memory)source).size()
Pointer[] compressed = {new Pointer(1024), new Pointer(1024)};
IntByReference intByReference = new IntByReference();
字节**ppcCompressed
-工作完成后,函数应填充ppcCompressed引用。我想我犯了一个错误,就是这样做的:

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

  return pointer;
}
String testData = "ABCDABCDABCDAAD";
Pointer source = setByteArrayPointer(testData);

(int) ((Memory)source).size()
Pointer[] compressed = {new Pointer(1024), new Pointer(1024)};
IntByReference intByReference = new IntByReference();
DWORD*pdwCompressedSize
-由压缩数据的函数大小返回。我以这种方式绘制它:

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

  return pointer;
}
String testData = "ABCDABCDABCDAAD";
Pointer source = setByteArrayPointer(testData);

(int) ((Memory)source).size()
Pointer[] compressed = {new Pointer(1024), new Pointer(1024)};
IntByReference intByReference = new IntByReference();
不确定这是否也是个好主意

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

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

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

任何帮助都将不胜感激。多谢各位

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

最后,主要问题是处理程序声明和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

释放内存并关闭


我认为主要的问题是对压缩值使用
指针(1024)
。使用
内存(1024)
分配本机内存。Windows中的
BOOL
也映射到
int
。任何非零值都是
true
。在运行时使用内存作为数组返回异常
java.lang.IllegalArgumentException:不支持的数组参数类型:class com.sun.jna.Memory
,看起来
内存
不能用作数组。我改为使用单个对象,并将
BOOL
映射到
int
,因此我的最终方法声明如下:
int-xcompress(WString-hComp,Pointer-pcSource,int-dwSourceSize,Memory-ppcCompressed,IntByReference-pdwCompressedSize,int-bEndOfData)我仍然得到了相同的错误:(文档说需要首先初始化XceedZip对象的句柄。这是必须作为HXCEEDCMP参数传递的指针:
ppcCompressed
参数可能只是指向压缩数据写入的内存块的指针,即
新指针ByReference(内存)
@cubrr我正在阅读文档,初始化了一个句柄,但我没有显示这个内部代码。
HXCEEDCMP
是我的Java代码中的一个
WString
,尽管它对
xceedcompression
工作正常,但在将它传递到
xcompression
方法后会导致问题。为了快速测试,我通过了完全引用
xcompress hComp
,我不再有无效的内存访问。但是我不确定xcompress/xdecompress方法返回的数据是否正确,看起来我现在得到了一些随机值。我尝试将
HXCEEDCMP
声明为指针,我同意
PointerByReference