Search code examples
javadelphidllmappingjna

Java JNA Mapping in Delphi Dll function


How do i map this function with JNA:

Delphi Dll Function Code:

function send_command (const command : byte; var size : byte; var data : pbyte) : integer; stdcall external 'comunication.dll';

Use example in Delphi Example Program:

send_command (cmdCLOCK_ADJUST, tam, pb);

Where:

const 
    cmdCLOCK_ADJUST = $18;

var
   tam : byte;
   pb, p : pbyte;

begin
   ...
    tam = 7;
    p:= pb;
       for i:= 1 to tam do
          begin
            p^:= Dados [i];
            inc (p)
          end;
    send_command (cmdCLOCK_ADJUST, tam, pb);
    freemem (pb);
   ...
end

The int value that is returned can be 0 for Error or 1 for right execution;

My suggestion is:

JNA Java Function Code:

int send_command(byte command, byte size, byte[] data);

The problem is that the function of the dll returns 0. I also tried other Datatypes, but it hasn't worked jet. I think the problem is that the dll function can't write to the parameter data.


Solution

  • It looks like your Delphi code is actually wrong.

    The size parameter appears to be a means to pass the length of the data from the caller to the callee. As such it should not be a var parameter.

    The data parameter appears to be a pointer to a buffer allocated by the caller. Again, that should not be a var parameter. Just a plain PByte, passed by value.

    Which would make the Delphi code be like this:

    function send_command(const command: Byte; size: Byte; data: PByte): Integer; 
      stdcall external 'comunication.dll';
    

    And then the Delphi code would match your Java code.

    Of course, I've had to make a number of guesses to write this answer. Guesses based on my experience of such problems, but guesses all the same. The real lesson that you should take away from this is that an interface is not specified by the types of its parameters. You also need to specify the semantics of the parameter passing.

    So, when you have a PByte paramerer, is that a pointer to a single byte, or a pointer to an array? If the latter, how large is the array. And so on. You need to specify all of this information to define an interface.

    If you really cannot change the DLL, then you'll need to pass the size and data parameters by reference, even though they appear to have value semantics. This answer covers passing by reference in JNA: How do I get a java JNA call to a DLL to get data returned in parameters?