2
votes

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.

1
The data parameter is the problem. the callee passes a pointer out? Really. Please show sample calling code in Pascal, or the documentation. - David Heffernan
I added a example, David. - Rafael Guerra
That doesn't add any more information. We cannot see what the types are. Who allocates the memory. And so on. You aren't going to be able to make progress until you can work out the semantics of the interface. Knowing the types is not enough. Since data is a var parameter of type pbyte, one assumes that the callee allocates the memory. Your code contradicts that. On the face of it, the problem is actually with the Delphi code which is wrong. - David Heffernan
Will I need to know what types of variables used in the dll code ? - Rafael Guerra

1 Answers

1
votes

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?