Java 在JNA中传递参数

Java 在JNA中传递参数,java,jna,Java,Jna,此代码填充生成的数据结构SCANNER\u FULL\u PLUS\u EX,然后调用函数ScanReadFull\u PlusEx()。这两个文件都是由jnavior生成的,应该创建一些文件,如Scan\u F.bmp等 对于windows 10 6位上的64位java,字节[512]中的文件名无法正确传递到dll。大多数情况下,文件名都是null public short SCANTEST(String fileName) { StringBuilder Bitma

此代码填充生成的数据结构SCANNER\u FULL\u PLUS\u EX,然后调用函数ScanReadFull\u PlusEx()。这两个文件都是由jnavior生成的,应该创建一些文件,如Scan\u F.bmp等

对于windows 10 6位上的64位java,字节[512]中的文件名无法正确传递到dll。大多数情况下,文件名都是null

    public short SCANTEST(String fileName) {

        StringBuilder BitmapNameF = new StringBuilder();
        StringBuilder BitmapNameR = new StringBuilder();
        StringBuilder BitmapNameF_IR = new StringBuilder();
        StringBuilder BitmapNameR_IR = new StringBuilder();
        StringBuilder BitmapNameF_UV = new StringBuilder();
        StringBuilder BitmapNameR_UV = new StringBuilder();

        SCANNER_FULL_PLUS_EX m_ScanFullPlusEx = new SCANNER_FULL_PLUS_EX();

        m_ScanFullPlusEx.Version = 0;
        m_ScanFullPlusEx.BrightnessFront = 100;
        m_ScanFullPlusEx.ThresholdFront = 100;
        m_ScanFullPlusEx.BrightnessRear = 100;
        m_ScanFullPlusEx.ThresholdRear = 100;
        m_ScanFullPlusEx.BitsPerPixel = 8;
        m_ScanFullPlusEx.ScanMode = 2;

        m_ScanFullPlusEx.ScanModeIR = 0;
        m_ScanFullPlusEx.ScanModeUV = 0;

        m_ScanFullPlusEx.dwImageWidth = 0;
        m_ScanFullPlusEx.dwImageHeight = 0;

        m_ScanFullPlusEx.pImageFront = new NativeLong(0);
        m_ScanFullPlusEx.dwImageSizeFront = 0;
        m_ScanFullPlusEx.pImageRear = new NativeLong(0);
        m_ScanFullPlusEx.dwImageSizeRear = 0;
        m_ScanFullPlusEx.pIR_ImageFront = new NativeLong(0);
        m_ScanFullPlusEx.dwIR_ImageSizeFront = 0;
        m_ScanFullPlusEx.pIR_ImageRear = new NativeLong(0);
        m_ScanFullPlusEx.dwIR_ImageSizeRear = 0;
        m_ScanFullPlusEx.pUV_ImageFront = new NativeLong(0);
        m_ScanFullPlusEx.dwUV_ImageSizeFront = 0;
        m_ScanFullPlusEx.pUV_ImageRear = new NativeLong(0);
        m_ScanFullPlusEx.dwUV_ImageSizeRear = 0;

        BitmapNameF.append(fileName + "F.bmp");
        BitmapNameR.append(fileName + "R.bmp");
        BitmapNameF_IR.append(fileName + "F_IR.bmp");
        BitmapNameR_IR.append(fileName + "R_IR.bmp");
        BitmapNameF_UV.append(fileName + "F_UV.bmp");
        BitmapNameR_UV.append(fileName + "R_UV.bmp");

        m_ScanFullPlusEx.ImageNameRear = Native.toByteArray(BitmapNameR.toString());
        m_ScanFullPlusEx.ImageNameFront = Native.toByteArray(BitmapNameF.toString());
        m_ScanFullPlusEx.IR_ImageNameFront = Native.toByteArray(BitmapNameF_IR.toString());
        m_ScanFullPlusEx.IR_ImageNameRear = Native.toByteArray(BitmapNameR_IR.toString());
        m_ScanFullPlusEx.UV_ImageNameFront = Native.toByteArray(BitmapNameF_UV.toString());
        m_ScanFullPlusEx.UV_ImageNameRear = Native.toByteArray(BitmapNameR_UV.toString());

        // wrap in 512 buffer
        byte[] f1 = new byte[512]; for (int i=0; i<m_ScanFullPlusEx.ImageNameRear.length;i++) f1[i]=m_ScanFullPlusEx.ImageNameRear[i]; m_ScanFullPlusEx.ImageNameRear = f1;
        byte[] f2 = new byte[512]; for (int i=0; i<m_ScanFullPlusEx.ImageNameFront.length;i++) f2[i]=m_ScanFullPlusEx.ImageNameFront[i]; m_ScanFullPlusEx.ImageNameFront = f2;
        byte[] f3 = new byte[512]; for (int i=0; i<m_ScanFullPlusEx.IR_ImageNameFront.length;i++) f3[i]=m_ScanFullPlusEx.IR_ImageNameFront[i]; m_ScanFullPlusEx.IR_ImageNameFront = f3;
        byte[] f4 = new byte[512]; for (int i=0; i<m_ScanFullPlusEx.IR_ImageNameRear.length;i++) f4[i]=m_ScanFullPlusEx.IR_ImageNameRear[i]; m_ScanFullPlusEx.IR_ImageNameRear = f4;
        byte[] f5 = new byte[512]; for (int i=0; i<m_ScanFullPlusEx.UV_ImageNameFront.length;i++) f5[i]=m_ScanFullPlusEx.UV_ImageNameFront[i]; m_ScanFullPlusEx.UV_ImageNameFront = f5;
        byte[] f6 = new byte[512]; for (int i=0; i<m_ScanFullPlusEx.UV_ImageNameRear.length;i++) f6[i]=m_ScanFullPlusEx.UV_ImageNameRear[i]; m_ScanFullPlusEx.UV_ImageNameRear = f6;

        short ret = MB2Library.INSTANCE.ScanReadFull_PlusEx(ByteBuffer.wrap(Native.toByteArray(gPort.Global)), m_ScanFullPlusEx, MB2Library.SCAN_OUTPUT_FORMAT_FILE_BMP);

        return ret;
    }
编辑1:

package mb2;

import java.util.StringTokenizer;

import java.util.Arrays;
import java.util.List;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.NativeLibrary;
import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.ptr.ByReference;
import com.sun.jna.ptr.PointerByReference;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.ByteByReference;
import com.sun.jna.ptr.DoubleByReference;
import com.sun.jna.ptr.FloatByReference;
import com.sun.jna.ptr.LongByReference;
import com.sun.jna.ptr.NativeLongByReference;
import com.sun.jna.ptr.ShortByReference;

public class SCANNER_FULL_PLUS_EX extends Structure {
    public int Version;
    public int BrightnessFront;
    public int ThresholdFront;
    public int BrightnessRear;
    public int ThresholdRear;
    public int BitsPerPixel;
    /** Front/Rear/Front-Rear */
    public int ScanMode;
    /** ( not yet implemented ) IR Front/Rear/Front-Rear */
    public int ScanModeIR;
    /** ( not yet implemented ) UV Front/Rear/Front-Rear */
    public int ScanModeUV;
    public int dwImageWidth;
    public int dwImageHeight;
    /**
     * Front CIS Image<br>
     * C type : HANDLE
     */
    public NativeLong pImageFront;
    public int dwImageSizeFront;
    /**
     * Rear CIS Image<br>
     * C type : HANDLE
     */
    public NativeLong pImageRear;
    public int dwImageSizeRear;
    /**
     * Front IR Image<br>
     * C type : HANDLE
     */
    public NativeLong pIR_ImageFront;
    public int dwIR_ImageSizeFront;
    /**
     * Rear IR Image<br>
     * C type : HANDLE
     */
    public NativeLong pIR_ImageRear;
    public int dwIR_ImageSizeRear;
    /**
     * Front UV Image<br>
     * C type : HANDLE
     */
    public NativeLong pUV_ImageFront;
    public int dwUV_ImageSizeFront;
    /**
     * Rear UV Image<br>
     * C type : HANDLE
     */
    public NativeLong pUV_ImageRear;
    public int dwUV_ImageSizeRear;
    /**
     * images path<br>
     * C type : TCHAR[512]
     */
    public byte[] ImageNameFront = new byte[512];
    /** C type : TCHAR[512] */
    public byte[] ImageNameRear = new byte[512];
    /** C type : TCHAR[512] */
    public byte[] IR_ImageNameFront = new byte[512];
    /** C type : TCHAR[512] */
    public byte[] IR_ImageNameRear = new byte[512];
    /** C type : TCHAR[512] */
    public byte[] UV_ImageNameFront = new byte[512];
    /** C type : TCHAR[512] */
    public byte[] UV_ImageNameRear = new byte[512];
    public SCANNER_FULL_PLUS_EX() {
        super();
    }
    protected List<String> getFieldOrder() {
        return Arrays.asList("Version", "BrightnessFront", "ThresholdFront", "BrightnessRear", "ThresholdRear", "BitsPerPixel", "ScanMode", "ScanModeIR", "ScanModeUV", "dwImageWidth", "dwImageHeight", "pImageFront", "dwImageSizeFront", "pImageRear", "dwImageSizeRear", "pIR_ImageFront", "dwIR_ImageSizeFront", "pIR_ImageRear", "dwIR_ImageSizeRear", "pUV_ImageFront", "dwUV_ImageSizeFront", "pUV_ImageRear", "dwUV_ImageSizeRear", "ImageNameFront", "ImageNameRear", "IR_ImageNameFront", "IR_ImageNameRear", "UV_ImageNameFront", "UV_ImageNameRear");
    }
    public SCANNER_FULL_PLUS_EX(Pointer peer) {
        super(peer);
    }
    public static class ByReference extends SCANNER_FULL_PLUS_EX implements Structure.ByReference {

    };
    public static class ByValue extends SCANNER_FULL_PLUS_EX implements Structure.ByValue {

    };
}
包mb2;
导入java.util.StringTokenizer;
导入java.util.array;
导入java.util.List;
导入com.sun.jna.Library;
导入com.sun.jna.Native;
导入com.sun.jna.nativellibrary;
导入com.sun.jna.NativeLong;
导入com.sun.jna.Pointer;
导入com.sun.jna.Structure;
导入com.sun.jna.ptr.ByReference;
导入com.sun.jna.ptr.PointerByReference;
导入com.sun.jna.ptr.IntByReference;
导入com.sun.jna.ptr.ByteByReference;
导入com.sun.jna.ptr.DoubleByReference;
导入com.sun.jna.ptr.FloatByReference;
导入com.sun.jna.ptr.LongByReference;
通过引用导入com.sun.jna.ptr.nativelong;
导入com.sun.jna.ptr.ShortByReference;
公共类SCANNER\u FULL\u PLUS\u EX扩展结构{
公共int版本;
公共交通前线;
公共战线;
公共内部照明系统;
公共内部阈值后方;
公共整数比特像素;
/**前/后/前/后*/
公共int扫描模式;
/**(尚未实施)红外前/后/前-后*/
公共int扫描模式;
/**(尚未实施)紫外线前/后/前-后*/
公共int扫描模式;
公共图像宽度;
公共高度;
/**
*前CIS图像
*C型:手柄 */ 公共民族阵线; 公共int dwImageSizeFront; /** *后CIS图像
*C型:手柄 */ 公共土生青椒; 公共int dwImageSizeRear; /** *前红外图像
*C型:手柄 */ 公共民族阵线; 公共int dwIR_ImageSizeFront; /** *后红外图像
*C型:手柄 */ 公共国家公园; 公共int dwIR_ImageSizeRear; /** *正面UV图像
*C型:手柄 */ 公共国家广场; 公共int dwUV_ImageSizeFront; /** *后部UV图像
*C型:手柄 */ 公共国家公园; 公共int dwUV_ImageSizeRear; /** *图像路径
*C类型:TCHAR[512] */ 公共字节[]ImageNameFront=新字节[512]; /**C类型:TCHAR[512]*/ 公共字节[]ImageNameRear=新字节[512]; /**C类型:TCHAR[512]*/ 公共字节[]IR_ImageNameFront=新字节[512]; /**C类型:TCHAR[512]*/ 公共字节[]IR_ImageNameRear=新字节[512]; /**C类型:TCHAR[512]*/ 公共字节[]UV_ImageNameFront=新字节[512]; /**C类型:TCHAR[512]*/ 公共字节[]UV_ImageNameRear=新字节[512]; 公共扫描仪\u满\u加上\u EX(){ 超级(); } 受保护列表getFieldOrder(){ 返回数组,“pUV_ImageFront”、“dwUV_ImageSizeFront”、“pUV_ImageRear”、“dwUV_ImageSizeRear”、“ImageNameFront”、“ImageNameRear”、“IR_ImageNameFront”、“IR_ImageNameRear”、“UV_ImageNameFront”、“UV_ImageNameRear”); } 公共扫描仪\u满\u加上\u EX(指针对等){ 超级(对等); } 公共静态类ByReference扩展SCANNER\u FULL\u PLUS\u EX实现结构。ByReference{ }; 公共静态类ByValue扩展了SCANNER\u FULL\u PLUS\u EX实现Structure.ByValue{ }; }
欢迎来到人类的奇妙世界

您仅与
字符串
参数一起使用。这将返回:

使用getDefaultStringEncoding()返回的编码,与给定字符串等效的以NUL结尾的字节缓冲区

在字符串和字节数组之间转换时,不指定编码通常是一种不好的做法。在这种情况下,您实际上希望使用默认的系统编码,但指定该编码很有用,并且在此过程中,了解它在做什么

默认的Windows编码是UTF-16,它使用16位来表示字符(
wchar\u t
在C中)。对于ASCII字符串,就像您正在使用的字符串一样,这意味着您的字节数组以交替的0字节和8位字符字节结束。(请随意插入代码并输出
Arrays.toString(f1)
亲自看一下!)

C结构使用的数组。这可以是单个字节,也可以是两个字节,具体取决于您的编码(这将匹配
Native.toByteArray()

因此,这里的默认编码很好,只是您需要知道该编码是什么,以便正确调整结构的大小。您正在传递512字节数组,而您可能需要512-TCHAR数组(1024字节)

但是,JNA结构必须知道它们的总字节大小,并且JNA中没有映射
TCHAR
。因此,您必须计算
CHAR\u WIDTH
,然后将512乘以结构中的该值。(在JNA源代码中搜索
CHAR\u WIDTH
,以获取这方面的示例。)

(编辑1)

感谢您提供了JNA映射。通常,当JNA映射的函数/结构出现错误时,首先要看的是类型映射。在您的情况下,除了如上所述的不正确的
TCHAR
byte
的映射之外,您还将
句柄
映射为
NativeLong
。这不正确在Windows上工作:
HANDLE
扩展自
PointerType
,指针匹配操作系统位,64位Windows上的64位也是如此。Windowspackage mb2; import java.util.StringTokenizer; import java.util.Arrays; import java.util.List; import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.NativeLibrary; import com.sun.jna.NativeLong; import com.sun.jna.Pointer; import com.sun.jna.Structure; import com.sun.jna.ptr.ByReference; import com.sun.jna.ptr.PointerByReference; import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.ByteByReference; import com.sun.jna.ptr.DoubleByReference; import com.sun.jna.ptr.FloatByReference; import com.sun.jna.ptr.LongByReference; import com.sun.jna.ptr.NativeLongByReference; import com.sun.jna.ptr.ShortByReference; public class SCANNER_FULL_PLUS_EX extends Structure { public int Version; public int BrightnessFront; public int ThresholdFront; public int BrightnessRear; public int ThresholdRear; public int BitsPerPixel; /** Front/Rear/Front-Rear */ public int ScanMode; /** ( not yet implemented ) IR Front/Rear/Front-Rear */ public int ScanModeIR; /** ( not yet implemented ) UV Front/Rear/Front-Rear */ public int ScanModeUV; public int dwImageWidth; public int dwImageHeight; /** * Front CIS Image<br> * C type : HANDLE */ public NativeLong pImageFront; public int dwImageSizeFront; /** * Rear CIS Image<br> * C type : HANDLE */ public NativeLong pImageRear; public int dwImageSizeRear; /** * Front IR Image<br> * C type : HANDLE */ public NativeLong pIR_ImageFront; public int dwIR_ImageSizeFront; /** * Rear IR Image<br> * C type : HANDLE */ public NativeLong pIR_ImageRear; public int dwIR_ImageSizeRear; /** * Front UV Image<br> * C type : HANDLE */ public NativeLong pUV_ImageFront; public int dwUV_ImageSizeFront; /** * Rear UV Image<br> * C type : HANDLE */ public NativeLong pUV_ImageRear; public int dwUV_ImageSizeRear; /** * images path<br> * C type : TCHAR[512] */ public byte[] ImageNameFront = new byte[512]; /** C type : TCHAR[512] */ public byte[] ImageNameRear = new byte[512]; /** C type : TCHAR[512] */ public byte[] IR_ImageNameFront = new byte[512]; /** C type : TCHAR[512] */ public byte[] IR_ImageNameRear = new byte[512]; /** C type : TCHAR[512] */ public byte[] UV_ImageNameFront = new byte[512]; /** C type : TCHAR[512] */ public byte[] UV_ImageNameRear = new byte[512]; public SCANNER_FULL_PLUS_EX() { super(); } protected List<String> getFieldOrder() { return Arrays.asList("Version", "BrightnessFront", "ThresholdFront", "BrightnessRear", "ThresholdRear", "BitsPerPixel", "ScanMode", "ScanModeIR", "ScanModeUV", "dwImageWidth", "dwImageHeight", "pImageFront", "dwImageSizeFront", "pImageRear", "dwImageSizeRear", "pIR_ImageFront", "dwIR_ImageSizeFront", "pIR_ImageRear", "dwIR_ImageSizeRear", "pUV_ImageFront", "dwUV_ImageSizeFront", "pUV_ImageRear", "dwUV_ImageSizeRear", "ImageNameFront", "ImageNameRear", "IR_ImageNameFront", "IR_ImageNameRear", "UV_ImageNameFront", "UV_ImageNameRear"); } public SCANNER_FULL_PLUS_EX(Pointer peer) { super(peer); } public static class ByReference extends SCANNER_FULL_PLUS_EX implements Structure.ByReference { }; public static class ByValue extends SCANNER_FULL_PLUS_EX implements Structure.ByValue { }; }
private static final int CHAR_WIDTH = Boolean.getBoolean("w32.ascii") ? 1 : 2;