How can I receive a string from FPC DLL?

327 Views Asked by At

How can I receive a string from a FPC DLL? I would like to send two pointers concat them and receive the result in another string in Delphi.

library Test;

{$mode Delphi}

uses
  Classes;

function Concat(const S1, S2: PWideChar): String; cdecl;
begin
  Result := S1 + S2;
end;

exports
  Concat name 'Concat';

begin
end.
1

There are 1 best solutions below

21
On BEST ANSWER

In Delphi, a String is a complex, structured type with many details managed for you by the compiler and RTL 'magic' that hides these details. In particular, for 'long strings' there is a reference count and a length and, depending on the Delphi version involved, possibly other information.

Any DLL cannot know the details of precisely what information is required to be returned (or may be present in) any 'string' variables (or results) that an application may require. The DLL may not even be called by a Delphi program at all, in which case the 'string' type will be quite different again.

For this reason, a DLL will usually choose to deal with strings as simple 'C'-style pointer to char types. That is, some pointer to a null terminated region of memory. The caller of the DLL must then also ensure to exchange 'string' values with the DLL accordingly.

In the case of some function returning a value, the issue is complicated by the fact that allocation of the area of memory required to hold the result must be performed by the caller, with the function in the DLL taking appropriate steps to ensure that the memory supplied is sufficient. Applying these principles in this case results in a DLL routine that might look similar to this:

function Concat(const S1, S2, DEST: PWideChar; const aMaxLen: Integer): Boolean; cdecl;
begin
  // left as exercise
end;

This is a simple implementation that returns TRUE if aMaxLen is sufficient to accommodate the concatenated result. You should also consider other behaviours of the function under a variety of conditions (eg. S1 or S2 or both are NIL, aMaxLen is too big, etc).

Whatever implementation choices are made for performing the concatenation (left as an exercise for you), the result of the function call must be to place the result in the buffer pointed to by DEST.

The caller must then also ensure that a buffer of sufficient length is provided and the correct length indicated in the call:

var
  a, b, ab: WideString;  // Or: String or UnicodeString in Delphi 2009 and later
begin
  a := 'foo';
  b := 'bar';

  // Make sure 'ab' is big enough to hold the concatenated result of a + b
  SetLength(ab, Length(a) + Length(b));

  if Concat(PWideChar(a), PWideChar(b), PWideChar(ab), Length(ab)) then
     // success:  ab == 'foobar'
  else
     // something went wrong
end;

The question has to be asked though: Why are you doing this in an FPC DLL when Delphi already handles the concatenation of strings quite comfortably ? O.o