2011-12-01 10 views
7

Je reçois cette erreur:E2010 Types incompatibles, pourquoi?

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

Ce qui suit est la partie pertinente du code à partir JwaStrSafe.pas (de Jedi Api), Je compile avec le symbole UNICODE défini:

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} 

Je reçois l'erreur sur l'appel de StringCchCopyExW, sur le paramètre ppszDestEnd. En regardant la définition de type je comprends que PSTRSAFE_LPTSTR est un type de pointeur à STRSAFE_LPTSTR qui est juste un alias de STRSAFE_LPWSTR, pourquoi PSTRSAFE_LPTSTR et PSTRSAFE_LPWSTR sont-ils incompatibles?

Solution
Merci à l'explication de David I remplacé

PSTRSAFE_LPTSTR = ^STRSAFE_LPTSTR; 

avec

PSTRSAFE_LPTSTR = PSTRSAFE_LPWSTR; 

maintenant le code compile sans erreur.

Merci

+2

Quelle version de Delphi utilisez-vous? –

+0

Je suis usind Delphi XE2 –

Répondre

3

je peux reproduire ce assez facilement dans XE2, et j'imagine que ce sera le même comportement dans toutes les autres versions. Pour le rendre plus simple, je l'ai réduit à ceci:

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

Cela produit également E2010. Toutefois, si vous activez l'option type-checked pointers, le code se compile correctement. En fait, la documentation que les options du compilateur déclare:

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.


Merci à Ken White pour me montrant la rubrique d'aide utile Type Compatibility and Identity. Les extraits pertinents sont que les types T1 et T2 sont compatibles pour l'affectation si:

T1 and T2 are compatible pointer types.

La documentation indique également que les types sont de type compatibile si:

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

Donc ces documents le comportement observé et me conduit à cet exemple:

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

Donc, pour résumer:Lorsque les pointeurs vérifiés par type sont désactivés, les pointeurs sont compatibles avec l'affectation si les pointeurs sont du même type.

  • Lorsque les pointeurs vérifiés par type sont activés, les pointeurs sont compatibles si les pointeurs pointent sur le même type. Je dois avouer ignorer l'histoire et le raisonnement derrière le paramètre pointeur vérifié par type, donc je ne peux pas fournir aucune explication pour la raison pour laquelle le compilateur est tel qu'il est.

  • +3

    Cela pourrait aider: [Type Identity] (http://docwiki.embarcadero.com/RADStudio/en/Type_Compatibility_and_Identity). –

    +0

    @Ken Merci, ça m'a beaucoup aidé! –

    +0

    De rien. Vous y avez déjà mis beaucoup de travail sans le lien; Je ne voulais pas l'utiliser et voler votre travail. :) Beau travail - +1. –

    Questions connexes