2014-02-25 32 views
1

我在Delphi中從FPC DLL獲取String的長度時遇到問題。這很奇怪,因爲我可以從DLL中取回String,但我無法獲得它的長度。FPC和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. 

回答

3

String在Delphi 2009+中是UnicodeStringAnsiString在早期版本中。

String在FPC總是AnsiString,它從不映射到UnicodeString。而AFAIK,FPC的字符串類型與Delphi的字符串類型不是二進制兼容的。因此,您無法將德爾福AnsiString傳遞給FPC AnsiString,反之亦然,並且UnicodeString也是如此。

你不應該在DLL邊界反正路過String值,尤其是當多個編譯器都參與其中,特別是因爲你沒有使用FPC的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. 

德爾福:

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

沒有執行轉換,也沒有性能損失。如果UnicodeString爲空,則將'UnicodeString'強制轉換爲'PWideChar'只會檢索指向UnicodeString字符數據的指針或指向靜態'#0'字符的指針。 –

+0

PWideChar創造奇蹟! – user3060326

+0

FPC中的字符串總是AnsiString,Delphi中的AnsiString或UnicodeString似乎並不重要。最好強調FPC.AnsiString不等於Delphi.AnsiString。 –

1

不能跨越這個模塊邊界使用string。 Delphi類型與FPC類型簡單不同。確實,他們有相同的名字,但不會使他們成爲同一類型。

事實上,即使兩個模塊都使用相同的編譯器進行編譯,它們也會是不同的類型,分配給不同的堆並且不適用於互操作。在德爾福你可以使用Sharemem和完全相同的編譯器版本,但這是非常有限的。

使用互操作性友好類型,如UTF-16的PWideChar或UTF-8的PAnsiChar。這樣,你的圖書館不受限制,可以與任何事物互操作。

+0

@Ritsaert這就是我說的,我認爲。 –

+0

@Ritsaert我從來沒有說現在的類型是一樣的。其實我說他們是不同的句號。您只能通過強制使用相同的編譯器和共享內存管理器來使它們相同。我看不出有什麼問題。 –

+0

@DavidHeffernan解決方案是'{$ mode delphiunicode}'。我可以有本地的String interop。 – user3060326

相關問題