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项目编译选项

image

三、如果仅仅就一个文件需要约束一下呢?

在不需要用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了。

posted @ 2016-02-25 22:55  海利鸟  阅读(1886)  评论(0编辑  收藏  举报