2013-02-20 63 views
1

我經常讀到當編譯爲PChar時編譯器會做某種魔法。PChar/PWideChar/PAnsiChar演員中是否有編譯器魔法?

PChar的主要目的是調用外來代碼在期望字符的零終止陣列(C風格「串」)文庫。

PChar是Unicode Delphi中PWideChar的別名,在非Unicode的Delphi上是PAnsiChar的別名。

德爾福字符串(string = AnsiString/UnicodeString,我不是在談論WideString這裏,更不用說ShortString ...),另一方面有一個隱藏的長度,而不是終止字符。它們也被引用計數並在寫入時使用拷貝。

Delphi字符串是否會自動分配並保留一個字符長度並帶有隱式#0字符,以便更容易轉換爲PChar(PAnsiChar/PWideChar),或者編譯器在遇到轉換時檢查和調整字符串到PChar

+1

我不懷疑**大多數**開發者使用'PChar'及其同類的主要原因是調用外部代碼,但這不是他們的字面意思。它們是Delphi中定義的各種字符串類型的指針類型。從技術角度來看,這就是他們的全部。 – LaKraven 2013-02-20 13:25:26

+2

@LaKraven'PChar'周圍的所有魔法使它不僅僅是一個指針。 – 2013-02-20 13:33:14

回答

10

的過程如下:

  • 如果字符串s具有長度大於零,則PChar(s)指針返回到該字符串的內容的第一個元素。因爲string被設置爲隱藏空終止符不需要做更多的事情。
  • 如果字符串s具有長度爲零,則PChar(s)的指針返回到的含有空終止內存塊。

作爲實現細節,從PChar(nil)返回的空終止符是在編譯模塊的只讀部分中分配的全局常量。

爲了使PChar(PAnsiChar/PWideChar)更容易轉換,Delphi字符串是否會自動分配並保留一個char長度並帶有隱式#0字符?

是。

神奇的,如果你能叫的話,就是:對空字符串

  1. 使用PChar()返回一個指向空終止符。
  2. 德爾福維持在字符串末尾的隱藏空終止符。
+0

你會怎麼稱呼「魔術」,有沒有更好的術語? – 2013-02-20 14:09:22

+2

@Jens - 也許是'內部編譯器'?當編譯器看到PChar強制轉換時,它會生成一個對'_UStrToPWChar'的調用。 – 2013-02-20 14:12:13

+1

@SertacAkyuz聽起來很合理。用俗語說可能是「特殊處理」?畢竟,與普通演員相比,編譯器在這裏做了一些不尋常的事情。 – 2013-02-20 14:17:22

3

字符串變量內部是一個指針到含有前綴,字符和空終止的結構。雖然結構從前綴(包含字符串長度,引用計數,字符大小和代碼頁)開始,但指針指向第一個字符,因此將其轉換爲PChar非常簡單。

字符串 - > PChar鑄造背後的魔力始終是PChar(S) <> nil,即使字符串是空的(S = ''Pointer(S) = nil)。Pointer(S) do,PChar(S)調用一個函數來檢查Pointer(S)是否爲零,如果Pointer(S) = nil返回一個指向虛擬空字符串的指針而不是nil(即指向空值終止符的指針),而不是返回字符串變量指針虛擬空字符串)。

+1

這是Rob Kennedy給出的一個很好的答案,它解釋了內部結構:http://stackoverflow.com/questions/549469/what-happens-when-ansistring-is-cast-to-pansistring – 2013-02-20 14:22:24

+1

這裏是XE3官方文檔:http://docwiki.embarcadero.com/RADStudio/XE3/en/Internal_Data_Formats#Long_String_Types – 2013-02-20 14:23:36