E2010不兼容的类型,为什么?
我得到这个错误: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;
现在的代码编译没有错误。
感谢
我可以在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.
所以,总结一下:
- 当禁用类型检查的指针时,如果指针的类型相同,则指针是分配兼容的。
- 当启用类型检查指针时,如果指针指向相同的类型,则指针是分配兼容的。
我不得不承认对类型检查指针设置背后的历史和推理一无所知,所以我不能提供任何解释为什么编译器是这样的。
这可能有助于:[Type Identity](http://docwiki.embarcadero.com/RADStudio/en/Type_Compatibility_and_Identity)。 –
@Ken谢谢,这帮了很大的忙! –
不客气。如果没有链接,你已经投入了大量工作。我不想使用它并窃取你的工作。 :)不错的工作 - +1。 –
您使用的是什么版本的Delphi? –
我是usind Delphi XE2 –