Domanda

Sto avendo problemi a ottenere la lunghezza di String in Delphi da una DLL FPC.Il che è strano perché posso ottenere il String torna dalla DLL ma non riesco a ottenere la sua lunghezza.

Delphi:

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.

PCF:

library project1;

{$mode ObjFPC}{$H+}

uses
  Classes;

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

exports Test;

end.
È stato utile?

Soluzione

String in Delphi 2009 + è UnicodeString, e AnsiString nelle versioni precedenti.

String in FPC è sempre AnsiString, non mappa mai a UnicodeString.E AFAIK, i tipi di stringhe di FPC non sono comunque compatibili con i tipi di stringhe di Delphi.Quindi non puoi passare un Delphi AnsiString ad un FPC AnsiString e viceversa, e lo stesso per UnicodeString.

Non dovresti passare String valori sopra il limite DLL comunque, specialmente quando sono coinvolti più compilatori e soprattutto perché non si utilizzano FPC Delphi modalità.È necessario riprogettare la DLL per essere più portatile, ad es:

PCF:

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.

Delphi:

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.

Altri suggerimenti

Non puoi usare string attraverso questo limite del modulo.Il tipo Delphi è semplicemente diverso dal tipo FPC.È vero che hanno lo stesso nome ma questo non li rende dello stesso tipo.

Infatti, anche se entrambi i moduli fossero compilati con lo stesso compilatore, sarebbero tipi diversi, allocati da heap diversi e non validi per l'interoperabilità.A Delphi puoi usare Sharemem e la stessa identica versione del compilatore, ma che è piuttosto vincolante.

Utilizzare un tipo di interoperabilità amichevole come PWideChar per UTF-16 o PAnsiChar per UTF-8.In questo modo la tua libreria non è vincolata e può interagire con qualsiasi cosa.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top