Pregunta

Tengo problemas para conseguir la longitud String en Delphi desde una DLL FPC.Lo cual es extraño porque puedo conseguir el String desde la DLL pero no puedo obtener su longitud.

Delfos:

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.
¿Fue útil?

Solución

String en Delphi 2009+ es UnicodeString, y AnsiString en versiones anteriores.

String en FPC es siempre AnsiString, nunca se asigna a UnicodeString.Y AFAIK, los tipos de cadenas de FPC no son compatibles binariamente con los tipos de cadenas de Delphi de todos modos.Entonces no puedes pasar un Delphi AnsiString a un FPC AnsiString y viceversa, y lo mismo para UnicodeString.

no deberías estar pasando String valores por encima del límite de DLL de todos modos, especialmente cuando hay varios compiladores involucrados, y especialmente porque no está utilizando FPC Delphi modo.Necesita rediseñar su DLL para que sea más portátil, por ejemplo:

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.

Delfos:

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.

Otros consejos

No puede utilizar string a través del límite de este módulo.El tipo Delphi es simplemente diferente del tipo FPC.Es cierto que tienen el mismo nombre pero eso no los convierte en el mismo tipo.

De hecho, incluso si ambos módulos se compilaran con el mismo compilador, serían de tipos diferentes, estarían asignados en diferentes montones y no serían válidos para la interoperabilidad.En Delphi podrías usar Sharemem y exactamente la misma versión del compilador, pero eso es bastante restrictivo.

Utilice un tipo amigable para la interoperabilidad como PWideChar para UTF-16 o PAnsiChar para UTF-8.De esa manera su biblioteca no está limitada y puede interoperar con cualquier cosa.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top