Lazarus 1.44升级到1.6 UTF8处理发生变化了
首先这里真的要强调一下,由于Freepascal升级到3.0后,FPC的内部将整个代码处理由AnsiString改为了UTF8编码(RTL with default codepage UTF-8)。
一、对于部分老函数:
实际应用会发现如果使用了wndows API 比如
function GetAdaptersInfo(pAdapterInfo: PIP_ADAPTER_INFO; var pOutBufLen: ULONG): DWORD; stdcall;
{$EXTERNALSYM GetAdaptersInfo};
// // ADAPTER_INFO - per-adapter information. All IP addresses are stored as // strings // PIP_ADAPTER_INFO = ^IP_ADAPTER_INFO; {$EXTERNALSYM PIP_ADAPTER_INFO} _IP_ADAPTER_INFO = record Next: PIP_ADAPTER_INFO; ComboIndex: DWORD; AdapterName: array [0..MAX_ADAPTER_NAME_LENGTH + 3] of Char; Description: array [0..MAX_ADAPTER_DESCRIPTION_LENGTH + 3] of Char; AddressLength: UINT; Address: array [0..MAX_ADAPTER_ADDRESS_LENGTH - 1] of BYTE; Index: DWORD; Type_: UINT; DhcpEnabled: UINT; CurrentIpAddress: PIP_ADDR_STRING; IpAddressList: IP_ADDR_STRING; GatewayList: IP_ADDR_STRING; DhcpServer: IP_ADDR_STRING; HaveWins: BOOL; PrimaryWinsServer: IP_ADDR_STRING; SecondaryWinsServer: IP_ADDR_STRING; LeaseObtained: time_t; LeaseExpires: time_t; end; {$EXTERNALSYM _IP_ADAPTER_INFO} IP_ADAPTER_INFO = _IP_ADAPTER_INFO; {$EXTERNALSYM IP_ADAPTER_INFO} TIpAdapterInfo = IP_ADAPTER_INFO; PIpAdapterInfo = PIP_ADAPTER_INFO;
Description 保存的就是一个常规的字符串数组,如果是AnsiString很容易处理了,包含Ascii以外的字符,使用Utf8Encode(),也能够很好的支持,1.6版后默认 UTF8=AnsiString(CP_UTF8),结果就是对于没有标识的字符串,采用 UTF8Encode就失效了,那么AnsiToUtf8()如何呢,同样没有效果。
查看LazUTF8单元,多了几个函数包括 WinCPToUTF8(),对就是它,处理WinAPI接口字符串,显示正常了。
二、如果是整个项目怎么办呢?
FPC 3.0 增加-dDisableUTF8RTL项目编译选项
三、如果仅仅就一个文件需要约束一下呢?
在不需要用UTF8代码页的单元强制代码页{$codepage cp1252}就可以了。
lazarus的Unicode支持http://wiki.freepascal.org/LCL_Unicode_Support ,较老的解决方案,适合 1.44+2.64 ,以前的版本,到了1.6+3.0版需要好好理解一下http://wiki.freepascal.org/Better_Unicode_Support_in_Lazarus了。