使用FreePascal

时间:2016-09-27 07:13:10

标签: lazarus freepascal ansistring

我在这里找到了类似的主题,但是他们都没有我的问题的解决方案,所以我在一个新的线程中问它。

几天前,我更改了我正在开发的应用程序首选项的格式,从INI到JSON。

我使用jsonConf单元。

我用来在文件中保存键值对的代码示例如下所示。

Procedure TMyClass.SaveSettings();
var
  c: TJSONConfig;
begin
  c:= TJSONConfig.Create(nil);
  try
    c.Filename:= m_settingsFilePath; 
    c.SetValue('/Systems/CustomName', m_customName);
  finally
    c.Free;
  end;
end;

在我的代码中,m_customName是一个AnsiString类型变量。 TJSONConfig.SetValue过程要求键和值都是UnicodeString类型。该应用程序编译良好,但我收到警告

Warning: Implicit strung type conversion from "AnsiString" to "UnicodeString". 

有些消息警告称存在潜在的数据丢失。

当然我可以将所有内容更改为UnicodeString类型,但这样做风险太大。到目前为止,我没有看到任何问题忽略这些警告,但它们一直出现,它可能会导致不同的PC出现问题。

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:3)

为了避免警告,请进行显式转换,因为这样您告诉编译器您知道自己在做什么(我希望......)。如果c.SetValue期望的类型是Unicodestring(UTF16),m_customname应该声明为string,除非有充分的理由做不同的事情(见下文),否则你可能会触发不需要的内部转换。

默认情况下,Lazarus中的string是UTF8编码的。因此,您可以使用函数UTF8Decode()进行从UTF8到Unicode的转换,或UTF8ToUTF16()(单位 LazUtf8 )。

var
  c: TJSONConfig;
  m_customName: String;
...
  c.SetValue('/Systems/CustomName', UTF8Decode(m_customName));

您在上面说过,键值对位于文件中。然后转换取决于文件的编码。通常我在一个好的文本编辑器中打开文件并在某处找到编码 - 例如,NotePad ++在状态栏的右下角显示编码的名称。假设编码是代码页1252(Latin-1)的编码。这些是ansistrings,因此,您可以将从文件中读取的字符串声明为ansistring。因为在Lazarus中UTF8字符串是如此常见,所以没有从ansistring到Unicode的直接转换,您必须首先转换为UTF8。在 lconvencoding 单元中,您可以在各种编码之间找到许多转换例程。选择CP1252toUTF8()转到UTF8,然后应用UTF8Decode()最终获得Unicode。

var
  c: TJSONConfig;
  m_customName: ansistring;
...
  c.SetValue('/Systems/CustomName', UTF8Decode(CP1252ToUTF8(m_customName)));

FreePascal编译器3.0可以使用具有预定义编码的字符串自动处理许多这些转换。但我认为明确的转换非常清楚,看看发生了什么。并且fpc3.0仍然会发出你想要避免的警告......