• Delphi的数据类型PChar


    var
    s:string;
    pc:pchar;
    pb:pbyte;
    ac:array[1..100] of char;
    ab:array[1..100] of byte;
    i:integer;
    begin
    s:='this is a test';
    pc:=pchar(s); //string->pchar
    pb:=pbyte(pc); //pchar->pbyte
    for i:=1 to length(s) do
    begin
    ac[i]:=s[i]; //string->arrary of char
    ab[i]:=byte(s[i]); //string->arrary of byte
    end;
    s:=pc; //pchar->string
    s:=string(pb); //pbyte->string
    s:=c; //arrary of char->string;
    end;
    move(buffer^,pchar(@rbuf)^,bufferlength);这样是对的不过我不是太了解pchar(@rbuf)^啥意思,有人能详细的说一下吗?
    move(buffer^,//--取缓冲区指针解除引用的值;
    pchar(@rbuf)^,//--@rbuf:这是取你的接收缓冲区的入口地址。相当于:@rbuf[0];
    //pchar(@rubf)这是将你的接收缓冲区指针转换成PCHAR类型指针;也就是^char
    //(pchar(@rbuf))^这样来看就列清楚了,解除指针引用后取值,实际上就是取指针地址内的值了。
    bufferlength); move是在两个地址间拷贝数据,Move(D,S,Len)就是从S地址处开始拷贝Len个字节,然后在D地址开始的Len字节空间里存储。D,S并非一定要求是指针,比如
    Move(buffer, rbuf, bufferlength);
    或者
    Move(buffer, rbuf[1], bufferlength);
    或者更增加通用性:
    Move(buffer, rbuf[Low(rbuf)], bufferlength);
    都可以
    来自Delphi Help 关键字String to PChar conversions
    长字符串转换到PChar不是自动的。他们之间的不同点导致他们的转换存在问题。
    1,长字符串是引用计数的,而PChar不是
    2,赋值给长字符串是数据的拷贝,而PChar是指向数据的指针。
    3,长字符串是空止符结尾,并包含有字符串的长度。而PChar是简单的空止符结尾。( 空止符结尾指以#0结尾)
    procedure my_func(x: string);
    begin
        some_proc(PChar(x)); //参照第一条,这么做自己负责x的生存期
    end;
    function title(n: Integer): PChar;
    var
    s: string;
    begin
    s := Format('title - %d', [n]);
    Result := PChar(s); // 参照第2条,不能这么做
    end;
    关于Delphi 中 String (又叫 LongString、AnsiString) 与传统的 PChar的区别
    1. string 是 Delphi 编译器内在支持的(predefined or built-in),是Delphi 的一个基本数据类型,而 PChar 只是一个指向零终止字符串的指针;
    2. String 所存字符串是在堆(Heap)分配内存的,String 变量实际上是指向零终止字符串的指针,与此同时它还具有引用计数(reference count)功能,并且自身保存字符串长度,当引用计数为零时,自动释放所占用的空间。
    3.将 string 赋值给另一个string,只是一个简单的指针赋值,不产生 copy 动作,只是增加string的引用计数;
    4. 将一个 PChar 变量类型赋值给一个 string 变量类型会产生真正的 Copy 动作,即将 PChar 所指向的字符串整个copy到为string分配的内存中;
    5. 将 string 赋值给一个 PChar 变量类型,只是简单地将string的指针值赋值给PChar 变量类型,而string 的引用计数并不因此操作而发生变化,因为这种情况 PChar 会对 string 产生依赖,当string 的引用计数为零自动释放内存空间后,PChar很可能指向一个无效的内存地址,在你的程序你必须小心对付这种情况。
    6. 对 PChar 的操作速度要远远高于对 string 操作的速度,但 PChar 是一种落后的管理字符串的方式,而 string 则以高效的管理而胜出,PChar 它的存在只是为了兼容早期的类型和操作系统(调用 Windows API时会经常用到),建议平常使用 string。
    你的那个demo程序我认为设计得非常糟糕,基本上说不清问题:
    我设计的Demo程序:
    procedure TForm1.Button1Click(Sender: TObject);
    var
    P: PChar;
    S1, S2: string;
    begin
    S1 := '1234567ABCDE';
    S2 := S1;
    P := PChar(S1);
    ShowMessage(IntToStr(SizeOf(S1))); //获得 S1 变量的大小
    ShowMessage(IntToStr(integer(S1))); //获得 S1 指向的字符串的指针地址
    ShowMessage(IntToStr(integer(P))); //获得 P 指向的字符串的指针地址
    ShowMessage(IntToStr(integer(S2))); //获得 S2 指向的字符串的指针地址
    S1 := P;
    ShowMessage(IntToStr(integer(S1)));
    ShowMessage(IntToStr(integer(P)));
    ShowMessage(IntToStr(integer(S2)));
    end;
    分析代码要点:
    S2 := S1 验证我总结的第3点
    P := PChar(S1) 验证我总结的第5点
    S1 := P 验证我总结的第4点
    我这里按顺序显示的结果(您的结果可能与此不同,但不妨碍分析)
    4 <= S1 变量的大小
    4530660 <= S1 指向的字符串的指针地址
    4530660 <= P 指向的字符串的指针地址
    4530660 <= S2 指向的字符串的指针地址
    9780484 <= S1 指向的字符串的指针地址 (地址发生变化)
    4530660 <= P 指向的字符串的指针地址
    4530660 <= S2 指向的字符串的指针地址
    关于分析它的汇编代码,我认为没什么必要,先搞清楚这些基本的操作!
    如果不考虑太多的话,我们采用简单的方法:
    1:pchar to string:
    ansistring a;
    pchar b;
    a=string(b);
    2: string to pchar
    ansistring a;
    pchar b;
    b=pchar(a);
    不过类型不太安全的。

  • 相关阅读:
    微信小程序之自定义模态弹窗(带动画)实例
    微信小程序之底部弹框预约插件
    Android WiFi直连 双向通信
    基于SpringBoot的项目管理后台
    Android WiFi热点7.1以上版本适配
    Android蓝牙——HID开发
    命令行视频(ts/m3u8)下载工具 —— youtube-dl(ffmpeg 解码)
    cool 软件 —— Carnac(实时桌面显示按键)
    认识 ARM、FPGA
    scikit-learn 学习笔记-- Generalized Linear Models (三)
  • 原文地址:https://www.cnblogs.com/hackpig/p/1668811.html
Copyright © 2020-2023  润新知