delphi 变参函数:array of const

变参array of const深入研究.mht 立即下载

array of const
 
Delphi的Format函数大家都用得很多,第二个参数用着确实很方便。最近在数 据库开发应用中需要自己创建一个带array of const参数的函数,对于常用的类型String,Integer,Pointer处理都没什么问题,但当用到Widestring类型时却出错,摸索 了一上午,感觉获益良多。现在将问题、解决问题的思路、分析方法等一一道来,希望对诸君有所启发就达到了我写这篇文章的目的了!

环境:Winxp + D7
进入D7,在默认的新建工程中增加一过程Test(m: Array of const);
procedure TForm1.test(m: array of const);
var
i, zero: Integer;
s, t: String;
c: Char;
const
sBoolean: Array [Boolean] of string = ('False', 'True');
begin
s := '';
for i := 0 to High(m) do with m[i] do
    case VType of //写到这,按住Ctrl点击VType,打开System单元,将VType的枚举值贴到Case语句
      vtInteger:    (VInteger: Integer; VType: Byte);
      vtBoolean:    (VBoolean: Boolean);
      vtChar:       (VChar: Char);
      vtExtended:   (VExtended: PExtended);
      vtString:     (VString: PShortString);
      vtPointer:    (VPointer: Pointer);
      vtPChar:      (VPChar: PChar);
      vtObject:     (VObject: TObject);
      vtClass:      (VClass: TClass);
      vtWideChar:   (VWideChar: WideChar);
      vtPWideChar: (VPWideChar: PWideChar);
      vtAnsiString: (VAnsiString: Pointer);
      vtCurrency:   (VCurrency: PCurrency);
      vtVariant:    (VVariant: PVariant);
      vtInterface: (VInterface: Pointer);
      vtWideString: (VWideString: Pointer);
      vtInt64:      (VInt64: PInt64);
    end;
Delete(s, 1, 1);
Self.Caption := s;
end;
继续写,对各枚举值进行处理!这里作一下解释,Array of const正是由TVarRec类型组成的!
请看Case of语句中的代码:
      vtInteger: s := s + ';' + IntToStr(VInteger);
      vtBoolean: s := s + ';' + sBoolean[VBoolean];
      vtChar: s := s + ';' + VChar;
      vtExtended: s := s + ';' + FloatToStr(VExtended^);
      vtString:
        if Assigned(VString) then begin
          t := VString^;
          s := s + ';' + t;
        end;
      vtPointer:
        if Assigned(VPointer) then
          s := Format('%S; Pointer: $%X ',[s, Integer(VPointer)]);
      vtPChar:
        if Assigned(VPChar) then begin
          t := VPChar^;
          s := s + ';' + t;
        end;
      vtObject:
        if Assigned(VObject) then
          s := Format('%S; $%X ClassName: %S ',[s, Integer(@VObject), VObject.ClassName]);
      vtClass:
        if Assigned(VClass) then
          s := Format('%S; Class Reference $%X - ClassName: %S ',[s, Integer(VClass), VClass.ClassName]);
      vtWideChar:
        begin
          t := VWideChar;
          s := s + ';' + t;
        end;
      vtPWideChar:
        if Assigned(VPWideChar) then begin
          t := VPWideChar^;
          s := s + ';' + t;
        end;
      vtAnsiString:
        if Assigned(VAnsiString) then begin
          t := PChar(VAnsiString);
          s := s + ';' + t;
        end;
      vtCurrency:
        if Assigned(VCurrency) then
          s := s + ';' + FloatToStr(VCurrency^);
      vtVariant:
        if Assigned(VVariant) then
          s := s + '; This is variant ';
      vtInterface:
        if Assigned(VInterface) then
          s := Format('%S; Interface: $%X',[s, Integer(VInterface)]);
      vtWideString:
        if Assigned(VWideString) then begin
          t := PWideString(VWideString)^;
          s := s + ';' + t;
        end;
      vtInt64:
        if Assigned(VInt64) then
          s := s + ';' + IntToStr(VInt64^);

加上一按钮测试该函数
procedure TForm1.Button1Click(Sender: TObject);
var
ws: WideString;
begin
ws := 'dda这是一个测试dfa';
test([self, 'sdf', 2.3324, ws, TForm]);
end;

可以看到测试结果,变量ws的值没有显示出来,怎么办呢?

我们可以看到WideString类型的值是指针,我们就从这里着手,在事件中添加一句:
Button1.Caption := Format('$%X',[Integer(@ws)]);
此句的作用是显示出ws的地址
再在Test函数中也加上类似的语句,并注释掉无用的语句:
//t := PWideString(VWideString)^;
//s := s + ';' + t;
s := s + ';' + Format('$%X',[Integer(VWideString)]);
运行可看到二个地址不一样,说明Delphi对传入的参数数据作了复制
因此将其强制转换成PWidechar应该可以,增加一变量声明
w: WideString;

w := PWideString(VWideString)^;
s := s + ';' + w;
但运行结果却只显示一个字符,别沮丧,已经摸到门道了!

我 们知道Format可以处理Widestring类型,这里只得到一个字符,说明字符被截断了。Delphi中的字符串是以#0结 束,Widestring以二个#0结束,可以肯定w := PWideString(VWideString)^这句Delphi作转换时肯定将其默认作为AnsiString处理了。分析到这里已经可动手写下去 了.....

p: PByte;

        if Assigned(VWideString) then begin
          t := '';
          zero := 0;
          p := VWideString;
          repeat
            c := char(p^);
            inc(p);
            if c = #0 then
              inc(zero) else
              begin
                zero := 0;
                t := t + c;
              end;
          until zero = 2;
          s := s + ';' + t;
        end;

但是显示汉字却变成乱码了,而且处理也显得臃肿。到这里我们已经明白了,VWideString所指示的字符串是二字节宽字符串,而且Intel的字节顺序也是低位在前,高位在后。因此可用PWord进行处理!

删除c,zero,w变量,p改成:
p: PWord;

        if Assigned(VWideString) then begin
          t := '';
          p := VWideString;
          repeat
            t := t + widechar(p^);
            inc(p);
          until p^ = 0;
          s := s + ';' + t;
        end;
可以看到核心代码已经很精练了,运行已经显示正常,汉字也无乱码了!至此我们似乎是大功告成了,但静下来想想,Delphi支持WideString到String的转换,它也应该有这样的处理代码。
而 且在循环中t := t + widechar(p^);语句处下一断点,运行到断点处,再打开CPU窗口,看到看似简洁的代码,单此一句,编译器都要给它加上一大堆处理代码。找到系 统的字符串处理函数很有必要,经过在System.pas单元中搜索WideString,找到函数:procedure WideCharToStrVar(Source: PWideChar; var Dest: string);
呵呵,这正是我们要的!!!
现在循环语句及P变量都可删除了,代码我就省略了。

function   MakeStr(const   Args:   array   of   const):   string;  
   
  const  
      BoolChars:   array[Boolean]   of   Char   =   ('F',   'T');  
  var  
      I:   Integer;  
  begin  
      Result   :=   '';  
      for   I   :=   0   to   High(Args)   do  
          with   Args[I]   do  
              case   VType   of  
                  vtInteger:         Result   :=   Result   +   IntToStr(VInteger);  
                  vtBoolean:         Result   :=   Result   +   BoolChars[VBoolean];  
                  vtChar:               Result   :=   Result   +   VChar;  
                  vtExtended:       Result   :=   Result   +   FloatToStr(VExtended^);  
   
                  vtString:           Result   :=   Result   +   VString^;  
                  vtPChar:             Result   :=   Result   +   VPChar;  
                  vtObject:           Result   :=   Result   +   VObject.ClassName;  
                  vtClass:             Result   :=   Result   +   VClass.ClassName;  
                  vtAnsiString:   Result   :=   Result   +   string(VAnsiString);  
                  vtCurrency:       Result   :=   Result   +   CurrToStr(VCurrency^);  
                  vtVariant:         Result   :=   Result   +   string(VVariant^);  
                  vtInt64:             Result   :=   Result   +   IntToStr(VInt64^);  
   
          end;  
  end;  
   
  We   can   call   this   function   using   an   open   array   constructor   (see   Open   array   constructors).   For   example,  
   
  MakeStr(['test',   100,   '   ',   True,   3.14159,   TForm])  
   
  returns   the   string   "test100   T3.14159TForm".

四旋翼黑科技揭秘:如何利用PX4隐藏的角加速度数据提升控制性能 本文深入探讨了如何利用PX4飞控中隐藏的角加速度数据,结合增量非线性动态逆(INDI)控制方法,显著提升四旋翼无人机的控制性能。通过实战教程,指导开发者从数据订阅、INDI原理到代码实现,构建响应更快、鲁棒性更强的控制回路,有效应对突风与快速机动。 阅读详情

相关推荐

SigmaStudio进阶技巧:如何用ADAU1701实现60段EQ与防啸叫算法

本文深入探讨了如何在ADAU1701 DSP芯片上实现专业级音频处理系统。通过精密的资源规划与架构设计,详细讲解了构建高达60段参数均衡器(EQ)的有效方法,并集成了移频与自适应陷波双策略的智能防啸叫算法。内容涵盖从SigmaStudio工程优化、算法模块组合到系统联调实战的全流程,旨在帮助中高级开发者充分利用ADAU1701性能,打造稳定、高效的音频处理解决方案。

weixin_28256233的博客 384

Delphi中关于 array of const 变体开放数组参数

<br />变体开放数组参数   <br />      <br />    <br />    变体开发数组参数允许向单个过程或函数传递不同类型表达式的数组。要定义含有变体开放数组参数的例程,需要指定array     of     const作为参数类型。如,   <br />    <br />    procedure     DoSomething(A:     array     of     const);   <br />    <br />    这里声明了一个叫做DoSomething的

zyyjc的专栏 2796

python爬取巨潮资讯网所有股票年报数据

爬虫获取巨潮资讯网数据

qq_42752524的博客 6114

变参array of const深入研究

  Delphi的Format函数大家都用得很多,第二个参数用着确实很方便。最近在数据库开发应用中需要自己创建一个带array of const参数的函数,对于常用的类型String,Integer,Pointer处理都没什么问题,但当用到Widestring类型时却出错,摸索了一上午,感觉获益良多。现在将问题、解决问题的思路、分析方法等一一道来,希望对诸君有所启发就达到了我写这篇文章的目的了!环

king_xing的专栏 1169

全志 mipi屏幕和触摸驱动调试记录

mipi屏幕与触摸调试记录

u011996684的博客 3219

FFmpeg入门详解之110:RTSP协议讲解

TCP/IP 协议体系中的一个应用层协议,该协议定义了一对多应用程序如何有效地通过 IP 网络传送多媒体数据。RTSP在体系结构上位于RTP和RTCP之上,它使用TCP或UDP完成数据传输。HTTP与RTSP相比,HTTP传送HTML,而RTSP传送的是多媒体数据。正在上传…重新上传取消RTSP是基于文本的协议,采用ISO10646字符集,使用UTF-8编码方案。行以CRLF中断(\r\n:10,13:0x0A,0x0D),包括消息类型、消息头、消息体和消息长。

福优学苑@音视频+流媒体 2529

Open array parameters and array of const

This article describes the syntax and use of open array parameters, and the use of the "array of const" parameter type. It also describes the internals of these two similar types of parameters, discus

Avan_Lau的专栏 1595

Serdes之什么是(CDR)?

光收发器和电收发器使用的是我们所说的串行数据通信。在这种通信方式中,数据位是按顺序一个接一个地传输的。光收发器和电收发器使用的是我们所说的串行数据通信。在这种通信方式中,数据位是按顺序一个接一个地传输的。目前市场上大多数收发器都没有专用的时钟输入,因此时钟恢复和数据重新定时等功能是在收发器外部(即在主板上)进行的。接收端则需要恢复时钟以采样串行线上的数据。为了实现这一点,接收端需要一个与输入数据频率大致相同的时钟。通过使参考时钟与输入数据信号的跳变相位对齐,可以生成一个恢复的时钟。这被称为时钟恢复。

叫好与叫座虽然不是对立面,但想在同一个作品中达到双重效果很难。 2389

Delphi中动态调用DLL的方法

Delphi中动态调用dll的方法如下: function CallFunc(dllname, funcname: string; const param: array of const): DWORD; var hLib: THandle; pFunc: Pointer; intSize: Integer; begin Result := 0; hLib :=

小宇飞刀的BLOG 9194

【天工Godwork精品教程】天工3.1.7安装教程(附Godwork完整版下载地址)

本文讲解天工3.1.7安装过程(附Godwork完整版网盘下载地址)。 一、天工3.1.7安装教程 1. 安装GodWork-AT 3.1.7 2. 安装GodWork-AT 3.1.7补丁 3. 安装GodWork-EOS-Setup-2017B-1231 4. 安装GodWork-EOS补丁 5. 运行godwokr软件 6. 生成ZC码 7. 输入ZC码 8. eos插

智慧空间实验室 5283

产品包装质检实战:基于YOLOv5的智能包装合格检测系统全流程指南

摘要: 针对产品包装质检效率低、漏检率高的问题,本文提出基于YOLOv5的智能检测系统。系统通过采集包装缺陷数据(破损、缺标、封装不良等),利用YOLOv5实现多类别缺陷识别(准确率≥95%),并开发Flask Web界面实现检测可视化与报告生成。实验表明,该系统在30帧/秒的产线速度下可稳定运行,显著提升质检效率。项目涵盖数据标注、模型训练、系统开发全流程,具有工业落地价值,适用于智能制造场景的自动化质检需求。(149字)

LXY_LOVE36的博客 93

delphi中array of const 借鉴

http://blog.163.com/zhangzhifeng688@126/blog/static/16526275820114995153163/ delphi中array of const 借鉴 2011-05-09 09:51:53| 分类: Delphi | 标签: |字号大中小 订阅 在Delphi中关于Variant的用法示例(该文仅仅是备

l799623787的专栏 2137

飞牛NAS1.1.19更新后SSH连不上?两步快速恢复连接

飞牛NAS1.1.19版本更新后SSH无法连接😟,实则是官方安全策略升级默认关闭了该服务,本文分享两步实操配置恢复SSH连接💻,还同步了官方的设备安全配置建议,帮助用户兼顾使用与设备防护🔒。

XiaoqiangClub的博客 2098

[转]delphi 变参函数:array of const

[转]delphi 变参函数:array of const array of const Delphi的Format函数大家都用得很多,第二个参数用着确实很方便。最近在数据库开发应用中需要自己创建一个带array of const参数的函数,对于常用的类型String,Integer,Pointer处理都没什么问题,但当用到Widestring类型时却出错,摸索了一上午,感觉获

autumn20080101的专栏 737

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

delphi 变参函数:array of const 转帖收藏

array of const2008-03-11 10:20Delphi的Format函数大家都用得很多,第二个参数用着确实很方便。最近在数据库开发应用中需要自己创建一个带array of const参数的函数,对于常用的类型String,Integer,Pointer处理都没什么问题,但当用到Widestring类型时却出错,摸索了一上午,感觉获益良多。现在将问题、解决问

henreash的专栏 2842

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Delphi与VC如何实现变参函数,类似Format、sprintf的变长参数实现原理,va_list与Array of const...

几乎所有高级语言都实现了一个format函数用于处理不同类型的数据组合转换为字符串。 delphi中有format,FormatBuf,FmtStr等,VC中有sprintf,CString中的format等,都是相当常用且方便的函数。 这些函数使用起来与普通函数最大的区别就是其中一个参数的个数、类型、是不确定的,反过来说,就是参数是可变的,这个特点使得该类函数功能变得异常强大,当然也极其方便...

weixin_30684743的博客 251

Delphi中array of const应用

Delphi的Format函数大家都用得很多,第二个参数用着确实很方便。最近在数据库开发应用中需要自己创建一个带array of const参数的函数,对于常用的类型String,Integer,Pointer处理都没什么问题,但当用到Widestring类型时却出错,摸索了一上午,感觉获益良多。现在将问题、解决问题的思路、分析方法等一一道来,希望对诸君...

a572893208的博客 95

关于 array of const

之前应该参考一下:关于开放数组参数 //这是在 System 单元定义的一组标识数据类型的常量: vtInteger = 0; vtBoolean = 1; vtChar = 2; vtExtended = 3; vtString = 4; vtPointer = 5; vtPChar = 6; vtO...

weixin_30369087的博客 290

array of const转Variant数组

constructor TQJobExtData.Create(const AParams: array of const); var T: PVariant; I: Integer; begin New(T); T^ := VarArrayCreate([0, High(AParams)], varVariant); for I := 0 to High(AParams) d...

qq_31553911的博客 308

array of const

{A common error when working with PChars is to store a local variable in a data structure, or return it as a value. When your routine ends, the PChar disappears because it is a pointer to memory, 

Hank's Techblog 1161

[转]delphi中array of const 借鉴

原文地址:http://blog.163.com/zhangzhifeng688@126/blog/static/16526275820114995153163/ Delphi中关于 array of const 变体开放数组参数 . 变体开发数组参数允许向单个过程或函数传递不同类型表达式的数组。要定义含有变体开放数组参数的例程,需要指定a...

weixin_30708329的博客 126
上一篇: 浅谈Delphi2009控件移植
下一篇: delphi 字符串函数大全
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值