2011-12-01 149 views
7

我得到這個錯誤:E2010不兼容的類型,爲什麼?

[DCC Error] JwaStrSafe.pas(2277): E2010 Incompatible types: 'PSTRSAFE_LPWSTR' and 'PSTRSAFE_LPTSTR' 

以下是代碼從JwaStrSafe.pas相關部分(從絕API),我正在與所定義的符號UNICODE編譯:

type 

STRSAFE_LPWSTR = PWIDECHAR; 
PSTRSAFE_LPWSTR = ^STRSAFE_LPWSTR; 

{$IFDEF UNICODE} 
    STRSAFE_LPTSTR = STRSAFE_LPWSTR; 
    PSTRSAFE_LPTSTR = ^STRSAFE_LPTSTR; 
{$ELSE} 
    ... 
{$ENDIF} 

... 
//function declaration 
function StringCchCopyExW(
    {__out_ecount(cchDest)}pszDest : STRSAFE_LPWSTR; 
    {__in}cchDest : size_t; 
    {__in}const pszSrc : STRSAFE_LPCWSTR; 
    {__deref_opt_out_ecount(pcchRemaining^)}ppszDestEnd : PSTRSAFE_LPWSTR; 
    {__out_opt}pcchRemaining : PSize_t; 
    {__in}dwFlags : Cardinal) : HRESULT; stdcall; forward; external; 

... 
//var passed to function 
ppszDestEnd : PSTRSAFE_LPTSTR; 

... 

{$IFDEF UNICODE} 
    result := StringCchCopyExW(pszDest, cchDest, pszSrc, ppszDestEnd, pcchRemaining, dwFlags); 
{$ELSE} 
    result := StringCchCopyExA(pszDest, cchDest, pszSrc, ppszDestEnd, pcchRemaining, dwFlags); 
{$ENDIF} 

我在參數ppszDestEnd上得到StringCchCopyExW調用的錯誤。

看看類型定義我知道PSTRSAFE_LPTSTR是STRSAFE_LPTSTR的指針類型,它只是STRSAFE_LPWSTR的別名,爲什麼PSTRSAFE_LPTSTR和PSTRSAFE_LPWSTR不兼容?

解決方案
感謝David的解釋我更換

PSTRSAFE_LPTSTR = ^STRSAFE_LPTSTR; 

PSTRSAFE_LPTSTR = PSTRSAFE_LPWSTR; 

現在的代碼編譯沒有錯誤。

感謝

+2

您使用的是什麼版本的Delphi? –

+0

我是usind Delphi XE2 –

回答

3

我可以在XE2重現此很輕鬆了,和我想象它會表現在所有其他版本相同。爲了使它更簡單,我把它縮減到這個:

program PointerTypeCompatibility; 
{$APPTYPE CONSOLE} 
type 
    A = Integer; 
    B = Integer; 
var 
    ptA: ^A; 
    ptB: ^B; 
begin 
    ptA := ptB; 
end. 

這也產生E2010。但是,如果啓用type-checked pointers選項,則代碼將成功編譯。事實上該編譯器選項的文件指出:

In the {$T-} state, distinct pointer types other than Pointer are incompatible (even if they are pointers to the same type). In the {$T+} state, pointers to the same type are compatible.


感謝肯·懷特在有用的幫助主題Type Compatibility and Identity指着我。相關的提取物是該類型的T1和T2是轉讓兼容如果:

T1 and T2 are compatible pointer types.

該文檔還指出類型型compatibile如果:

Both types are (typed) pointers to the same type and the {$T+} compiler directive is in effect.

所以這個記錄了觀察到的行爲和讓我看看這個例子:

program PointerTypeCompatibilityTake2; 
{$APPTYPE CONSOLE} 
{$TYPEDADDRESS OFF} 
var 
    P1,P2: ^Integer; 
    P3: ^Integer; 
begin 
    P1 := P2;//compiles 
    P1 := P3;//E2008 Incompatible types 
end. 

所以,總結一下:

  • 當禁用類型檢查的指針時,如果指針的類型相同,則指針是分配兼容的。
  • 當啓用類型檢查指針時,如果指針指向相同的類型,則指針是分配兼容的。

我不得不承認對類型檢查指針設置背後的歷史和推理一無所知,所以我不能提供任何解釋爲什麼編譯器是這樣的。

+3

這可能有助於:[Type Identity](http://docwiki.embarcadero.com/RADStudio/en/Type_Compatibility_and_Identity)。 –

+0

@Ken謝謝,這幫了很大的忙! –

+0

不客氣。如果沒有鏈接,你已經投入了大量工作。我不想使用它並竊取你的工作。 :)不錯的工作 - +1。 –

相關問題