Доступ к указателям DLL через Java - PullRequest
0 голосов
/ 08 февраля 2019

Я использую Java (JNA) для доступа к коду 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.Пожалуйста посоветуй.

1 Ответ

0 голосов
/ 11 февраля 2019

Глядя на определение типа для функции, я бы сделал обоснованное предположение и сказал бы, что pData - это указатель массива, в который функция записывает прочитанную память.Вы можете использовать int[] прямо здесь.Поскольку состояние возвращается как параметр out через указатель, вы можете использовать ByteByReference.

. В Java long относится к 64-битному целому числу, эквивалентному long long в C ++.Поскольку типом является U32, вероятно, можно предположить, что он относится к 32-разрядному целому числу.Это будет int.Вы можете проверить соответствия типов JNA здесь .

Также обратите внимание, что, поскольку функция принимает 32-разрядное целое число для адреса, вы не можете передать 64-разрядные адреса функции.

Я бы предположил, что одно правильное отображение для этой функции будет следующим:

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

Если вашей функции действительно нужно только прочитать одно 32-разрядное целое число из памяти, вы можете изменить тип pDataна IntByReference и использовать его так же, как ByteByReference.

.

параметра status. Поскольку функция возвращает целое число, я думаю, что она возвращает количество прочитанных байтов.Если это так, важно убедиться, что это значение соответствует ожидаемому.Проверьте, что в документации библиотеки говорится о возвращаемом значении и состояниях ошибок.

Попробуйте это:

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
        );
    }
}
...