在調試器中,Named Thread 的處理器期待 FName 成員是 ANSI 字符,不是 Unicode,所以上面的聲明必須改成下面這樣:
type
TThreadNameInfo = record
FType: LongWord; // must be 0x1000
FName: PAnsiChar; // pointer to name (in user address space)
FThreadID: LongWord; // thread ID (-1 indicates caller thread)
FFlags: LongWord; // reserved for future use, must be zero
end;
在新版本中上述聲明已經修改,提示這段代碼是需要您注意早先版本中您手工創建並聲明的代碼需要您自己修改。
如果您需要在 Named Thread 中使用 Unicode 字符,您必須將字符串格式化成 UTF-8 編碼,調試器可以完全支持改編碼。例如:
ThreadNameInfo.FName := UTF8String('UnicodeThread_фис');
注意:C++ Builder 裡面一直使用的是正確的代碼,所以上述問題在 C++ Builder 中並不存在。
使用 PChar 轉換的指針運算
在 Tiburon 更早的版本中,並不是所有的指針類型都支持指針運算。因為這樣,為了讓無類型指針也支持指針運算,許多代碼都將其轉化成 PChar 操作。現在,可以使用 Tiburon 中的新編譯條件 {$POINTERMATH} 來指示編譯器允許指針運算,特別是允許 PByte 的指針運算。{$POINTERMATH ON/OFF} 可以打開/禁止對任意指針變量的運算,增減指針實際操作的是指針元素的大小。
下面的例子是一個將某類型指針轉換成 PChar 後的指針運算:
function TCustomVirtualStringTree.InternalData(Node: PVirtualNode): Pointer;
begin
if (Node = FRoot) or (Node = nil) then
Result := nil
else
Result := PChar(Node) + FInternalDataOffset;
end;
您應該將其修改成 PByte 而不是 PChar:
function TCustomVirtualStringTree.InternalData(Node: PVirtualNode): Pointer;
begin
if (Node = FRoot) or (Node = nil) then
Result := nil
else
Result := PByte(Node) + FInternalDataOffset;
end;
在上面的例子中,Node 真實的數據不是 PChar 的數據。將其強制轉換成 PChar 的操作在早先的版本中是正常的,因為早先版本中 SizeOf(Char) == Sizeof(Byte)。但是現在不同了,所以這樣的代碼必須從 PChar 改換成 PByte。如果不做這樣的更改,返回的 Pointer 將指向錯誤的數據。
變體開放數組(Variant Open Array)參數
如果你的代碼中有使用 TVarRec 類型去處理開放數組的話,你可能需要為其添加對 vtUnicodeString 的支持。參看下列示例:
procedure RegisterPropertIEsInCategory(const CategoryName: string;
const Filters: array of const); overload;
var
I: Integer;
begin
if Assigned(RegisterPropertyInCategoryProc) then
for I := Low(Filters) to High(Filters) do
with Filters[I] do
case vType of
vtPointer:
RegisterPropertyInCategoryProc(CategoryName, nil,
PTypeInfo(vPointer), );
vtClass:
RegisterPropertyInCategoryProc(CategoryName, vClass, nil, );
vtAnsiString:
RegisterPropertyInCategoryProc(CategoryName, nil, nil,
string(vAnsiString));
vtUnicodeString:
RegisterPropertyInCategoryProc(CategoryName, nil, nil,
string(vUnicodeString));
else
raise Exception.CreateResFmt(@sInvalidFilter, [I, vType]);
end;
end;