質問

FPC DLLからDelphiのStringの長さの長さの取得に問題があります。私はDLLからStringを取り戻すことができるので、これは奇妙なものですが、その長さを取得できません。

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.
.

FPC:

library project1;

{$mode ObjFPC}{$H+}

uses
  Classes;

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

exports Test;

end.
.

役に立ちましたか?

解決

Delphi 2009+のStringは、以前のバージョンのUnicodeString、およびAnsiStringです。

FPCのStringは常にAnsiStringで、UnicodeStringにマッピングされません。そしてAfaik、FPCの文字列型は、とにかくDelphiの文字列型とバイナリ互換ではありません。したがって、Delphi AnsiStringをFPC AnsiStringに、およびその逆に、およびUnicodeStringでも同じに渡すことはできません。

特に複数のコンパイラが関与している場合、特にFPCのStringモードを使用していないため、DLL境界よりもDelphi値を渡してはいけません。あなたはよりポータブルになるようにあなたのDLLを再設計する必要があります:

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.
.

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.
.

他のヒント

このモジュール境界にstringを使用することはできません。Delphi Typeは単にFPCタイプとは異なります。それらが同じ名前を持つが、それはそれらを同じ型にしません。

実際には、両方のモジュールが同じコンパイラでコンパイルされていても、異なるタイプになり、異なるヒープを割り当て、相互コールには無効です。Delphiでは、Sharememとまったく同じコンパイラバージョンを使用できますが、それはかなり制約です。

UTF-16のPWideCharやUTF-8のPAnsiCharなどの相互コップ式タイプを使用します。そのようにあなたのライブラリは制限されず、何でも相互に相互運用できます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top