【问题标题】:Accessing DLL pointers through Java通过 Java 访问 DLL 指针
【发布时间】:2019-02-08 01:53:03
【问题描述】:

我正在使用 Java (JNA) 访问 DLL 代码。这是我正在使用的 DLL:

U32 ReadMemU32(U32 Addr, U32 NumItems, U32* pData, U8* pStatus);

这是我的示例代码:

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.ptr.*;
import com.sun.jna.*;
import java.lang.*;
import java.util.*;

import com.sun.jna.*;
import java.lang.*;

public class DLL1 {

    @UserFunction(Description="DLL1 Java wrapper", Name = "DLL1")
    public static String DLL1(
        @UserFunction.Arg(Name = "Address", Description = "Register Address")
        String Address
    ) throws Exception {

        byte Status[] = new byte[1];
        PointerByReference Data = new PointerByReference ();

        long Addr = Long.parseLong(Address.substring(2, Address.length()));
        DllInterface.INSTANCE.ReadMemU32(Addr, 1, Data, Status);
        System.out.println("Data = " + Data);
        System.out.println("Data.getValue() = " + Data.getValue()); 

        return null;
    }

    // C++ function definition and tell which DLL to fetch
    public interface DllInterface extends Library {

        DllInterface INSTANCE = (DllInterface) Native.loadLibrary("<dll name>", DllInterface.class);

        long ReadMemU32(long Addr, long NumItems, PointerByReference pData, byte[] pStatus);
    }
}

我得到的结果是:

Data = allocated@0xe25ac90 (8 bytes)(com.sun.jna.ptr.PointerByReference@e25ac90)
Data.getValue() = native@0xaaaaaaaa

结果 (0xaaaaaaaa) 与我预期的不匹配。

我是 Java 新手,我不确定 PointerByReference 是否适合用于 U32* pData。请指教。

【问题讨论】:

    标签: java c++ dll jna


    【解决方案1】:

    查看函数的类型定义,我会做出一个有根据的猜测,并说pData 是函数写入读取内存的数组指针。你可以在这里直接使用int[]。由于状态是通过指针作为输出参数返回的,因此您可以使用ByteByReference

    在 Java 中,long 指的是一个 64 位整数,相当于 C++ 的 long long。由于类型是U32,因此可以安全地猜测它指的是一个 32 位整数。这将是一个int。你可以查看JNA的类型映射here

    还要注意,由于该函数接受 32 位整数作为地址,因此您不能将 64 位地址传递给该函数。

    我猜这个函数的一个正确映射是:

    int ReadMemU32(
        int address,
        int numItems,
        int[] pData,
        ByteByReference status
    );
    

    如果你的函数真的只需要从内存中读取一个32位整数,你可以将pData的类型改为IntByReference,并像status参数的ByteByReference一样使用它。

    由于函数返回一个整数,我猜它返回读取的字节数。如果是这样,请务必检查此值是否与您的预期相符。检查库文档中有关返回值和错误状态的内容。

    试试这个:

    import java.lang.*;
    import java.util.*;
    
    import com.sun.jna.*;
    import com.sun.jna.ptr.*;
    
    public class DLL1 {
    
        @UserFunction(Description="DLL1 Java wrapper", Name = "DLL1")
        public static String DLL1(
            @UserFunction.Arg(Name = "Address", Description = "Register Address")
            String Address
        ) throws Exception {
    
            String addressWithoutPrefix = Address.substring(2)
            int parsedAddress = Integer.parseInt(addressWithoutPrefix, 16)
    
            int bytesToRead = 1;
            int[] buffer = new int[bytesToRead];
    
            ByteByReference status = new ByteByReference(0);
    
            int BytesRead = DllInterface.INSTANCE.ReadMemU32(
                parsedAddress,
                bytesToRead,
                buffer,
                status
            );
    
            System.out.println("Status = " + status.getValue());
            System.out.println("Bytes read = " + bytesRead);
            System.out.println("Data = " + Arrays.toString(buffer));
    
            return null;
        }
    
        // C++ function definition and tell which DLL to fetch
        public interface DllInterface extends Library {
    
            DllInterface INSTANCE = (DllInterface) Native.loadLibrary("<dll name>", DllInterface.class);
    
            int ReadMemU32(
                int address,
                int numItems,
                int[] pData,
                ByteByReference status
            );
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-26
      • 2021-12-11
      • 1970-01-01
      • 2011-02-03
      • 1970-01-01
      相关资源
      最近更新 更多