码迷,mamicode.com
首页 > 其他好文 > 详细

用 Lazarus 开发 OPC Client 1 (关于字符集)

时间:2016-12-28 17:37:54      阅读:257      评论:0      收藏:0      [点我收藏+]

标签:条件编译   选项   async   部分   否则   方向   执行   cti   判断   

其实很早就打算在Lazarus里面做一个,要么在实际应用中时间太紧需要使用OPC了就用Delphi的程序改改,也就用了。

到了FPC3.0之后也就lazarus1.6以后,其核心对UTF8的全面支持,导致Delphi的很多程序都不能直接转移到Lazarus里面。明知山有虎偏向虎山行,OPC里面会大量用到PWideChar和OleVariant这是难点,本身技术上倒不是,但与Lazarus的融合就存在很多不不确定性。

OPC客户端的构建流程很简单

  1. 建立ActiveX服务器的引用
  2. 通过服务器接口的“组管理器”——构建组
  3. 通过组的条“目管理器”在该组添加“条目”,也就是工业领域说的“标签”——Tag
  4. 现在可以Read/Write读写标签了
  5. 如果希望效率,OPC提供的托管方式,也就是常常翻译为“订阅”的方法。以组为单位构建“订阅”。
  6. 如果成功将实现 OnChange 、AsyncRead、AsyncWrite (异步读写)。

期间每一步都要注意资源的释放!而且每一步又都要与字符串打交道,注意COM内部大量使用WideString,但微软的大师在设计自然是会大量用到指针的,所以PWideChar与FPC的String的交互就成了主要任务。关键问题字符串,不彻底解决就算构建成功也不能正常显示,更何况由于Lazarus的内部转换,基本就是构建不成功。

RTL,LCL默认都是UTF8这是有优势的,但很难驾驭,这也导致很多lazarus1.2x之前的很多解决方案失效,比如SysToUTF8和UTF8ToSys,跟踪发现

function UTF8ToSys(const s: string): string;
begin
  {$IFDEF UTF8_RTL}
  Result:=s;
  {$ELSE}
  if NeedRTLAnsi and (not IsASCII(s)) then
    Result:=UTF8ToAnsi(s)
  else
    Result:=s;
  {$ENDIF}
end;
注意这里面的条件编译{$IFDEF UTF8_RTL} 

导致这些过程\函数\方法有时候“生效”有时候“无效”主要是条件编译{$IFDEF UTF8_RTL}的作用,其实上次发的博文提到的FPC 3.0 增加-dDisableUTF8RTL项目编译选项,使参数保存在本项目里面。当配置完毕以上语句就可以执行到{$ELSE} 部分了。

整个现象这个让我懊恼了好久好久,总是不能明确结果,导致Lazarus程序字符串输出不能达到预期的效果,用了好多方法,甚至怀疑是否真的该放弃当时自己写的UTF8转换单元,使用系统自带功能的判断。幸好手头有两个项目一个有这个参数一个没有,结果导致截然不同的效果,当然有一个能准确实现设计意图否则也就不会去分析了——庆幸。最后还是看了[Lazarus] UTF8 RTL for Windows才想起。

方向明确了之后,要解决问题自然就是找出具体的办法处理字符串。

我们对待POleChar通常的解决办法是 PWchar(WideString(XXXstring));在Lazarus里面小工程例子项目没有问题,大了,也就是资源使用比较多也许到用的时候早就释放了。就必须用到StringToOleStr(XXXstring)了。

整合后得到如下过程函数

function UTF8StrToOleStr(const Source: UTF8String): PWideChar;
var
  vS: string;
begin
  vS     := UTF8ToSys(Source);
  // Result := POleStr(WideString(vS));
  Result := StringToOleStr(vS);
  if Result = nil then
    Result := ‘‘;
end;

function OleStrToUTF8Str(const Source: PWideChar): UTF8String;
var
  vS: string;
begin
  if Source = nil then
    Result := ‘‘
  else
    WideCharToStrVar(Source, vS);
  Result := SysToUTF8(vS);
end;

现在记性太不好了,做个记录。

用 Lazarus 开发 OPC Client 1 (关于字符集)

标签:条件编译   选项   async   部分   否则   方向   执行   cti   判断   

原文地址:http://www.cnblogs.com/hieroly/p/6229584.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!