Question

J'ai du mal à obtenir la longueur String en Delphi à partir d'une DLL FPC.Ce qui est bizarre parce que je peux obtenir le String de retour de la DLL mais je n'arrive pas à obtenir sa longueur.

Delphes:

program Project2;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

function Test(const S: String): Integer; cdecl; external 'c:\Project1.dll';

var
    A: String;
begin 
    A := 'test';
    WriteLn(Test(A)); // 1 ?
    ReadLn;
end.

FPC :

library project1;

{$mode ObjFPC}{$H+}

uses
  Classes;

function Test(const A: String): Integer; cdecl; export;
begin
 Result := Length(A);
end;

exports Test;

end.
Était-ce utile?

La solution

String dans Delphi 2009+ est UnicodeString, et AnsiString dans les versions antérieures.

String dans FPC est toujours AnsiString, il ne correspond jamais à UnicodeString.Et AFAIK, les types de chaînes de FPC ne sont de toute façon pas compatibles binairement avec les types de chaînes de Delphi.Donc tu ne peux pas passer un Delphi AnsiString à un FPC AnsiString et vice versa, et de même pour UnicodeString.

Tu ne devrais pas passer String de toute façon, les valeurs dépassent les limites de la DLL, en particulier lorsque plusieurs compilateurs sont impliqués, et d'autant plus que vous n'utilisez pas les FPC. Delphi mode.Vous devez repenser votre DLL pour qu'elle soit plus portable, par exemple :

FPC :

library project1;

{$mode ObjFPC}
{$H+}

uses
  Classes;

function TestA(const A: PAnsiChar): Integer; cdecl; export;
begin
 Result := Length(A);
end;

function TestW(const A: PWideChar): Integer; cdecl; export;
begin
 Result := Length(A);
end;

exports TestA, TestW;

end.

Delphes:

program Project2;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

function Test(const S: PChar): Integer; cdecl; external 'Project1.dll' name {$IFDEF UNICODE}'TestW'{$ELSE}'TestA'{$ENDIF};

var
  A: String;
begin 
  A := 'test';
  WriteLn(Test(PChar(A)));
  ReadLn;
end.

Autres conseils

Vous ne pouvez pas utiliser string à travers cette limite de module.Le type Delphi est simplement différent du type FPC.Il est vrai qu’ils portent le même nom mais cela ne fait pas d’eux le même type.

En fait, même si les deux modules étaient compilés avec le même compilateur, ils seraient de types différents, alloués sur des tas différents et non valides pour l'interopérabilité.En Delphi, vous pouvez utiliser Sharemem et exactement la même version du compilateur mais c'est assez contraignant.

Utilisez un type convivial pour l'interopérabilité tel que PWideChar pour UTF-16 ou PAnsiChar pour UTF-8.De cette façon, votre bibliothèque n'est pas limitée et peut interagir avec n'importe quoi.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top