Delphi双指针使用

原创 2008年10月02日 00:17:00
        Delphi的指针功能实际上是很少有用到的,但是它对外封装了几个指针的类型还是可以用用,如
    PChar (=^Char),
    PPChar (=^PChar, 传说中的双指针,在Delphi5与它的以下版本可能没有这个类型,但可以自己建立,如:
    type 
    PPChar = ^PChar
)
等等。
        我也是在偶然的机会下碰到这个技术话题的。在写一个DELPHI的系统中,调用一个厂家提供的DLL(VC)时,代码类似如下:
DLL模块 
  1. int _stdcall getInfo(char* info)
实现部分         
  1. int _stdcall getTest(char* info)
  2. {
  3.    char* str = "Test";
  4.    // TODO: str业务处理
  5.    strcpy(info, str);
  6.    return 0;
  7. }
Delphi客户端程序
  1. function getInfo(info: PChar): string; stdcall; External '{ Dll 函数}';
  2. // 测试过程
  3. procedure Test;
  4. var
  5.   pStr: array[0..100of Char;
  6. begin
  7.   getTest(pStr);
  8.   ShowMessage(pStr);
  9. end;
        如上,经测试成功。
        大家可能就发现问题了,Delphi这边需要申请一个内存空间,如array[0..100], 或使用strAlloc,才能调用VC提供的DLL函数。否则就会报些大家最不愿意看见的内存地址错误,如:"Access violation at address 00423A69 in module 'Demo.exe'. Read of address 74736560."。
        但是大家有没有从业务功能上考虑,我怎么知道需要申请多少内存空间呢,换句话说,DELPHI调用这边就必须设个很大的空间,这样的程序设计是不是不太合理?!所以想到这,就考虑是不是应该让Dll的函数自己来申请内存空间。修改DLL:   
  1. int _stdcall getTest(char* info)
  2. {
  3.   char* str = "Test";
  4.   // TODO: str业务处理
  5.   info = (char*) malloc(sizeof(char) * strlen(str) + 1);  // 分配内存空间
  6.   strcpy(info, str);
  7.   info[strlen(str)] = 0x00; // 标记结束符
  8.   return 0;
  9. }
        调用代码修改pStr: PChar,如;
  1. procedure Test;
  2. var
  3.   pStr: PChar;
  4. begin
  5.   getTest(pStr);
  6.   ShowMessage(pStr);
  7. end;
        经调用,数据是出来了,可惜是乱码,在记事本中显示为“?”,至今也搞不清为撒。那就只能考虑别的方式吧。
        Delphi的PChar不是表示指针吗?那把getTest(pStr)改成getTest(@pStr)传地址进去如何,结果又报内存错误,如"Access violation at address 00403A8B in module 'Demo.exe'. Read of address 00200000."(这内存地址又换了一组)。
        delphi竟然传指针过来,那DLL是不是得改一下,用双指针试试,如:
  1. int _stdcall getTest(char* *info)
  2. {
  3.   char* str = "Test";
  4.    // TODO: str业务处理
  5.    *info = (char*) malloc(sizeof(char) * strlen(str) + 1); // 分配内存空间
  6.   char* c = *info;
  7.   strcpy(c, str);
  8.   c[strlen(str)] = 0x00;
  9.   return 0;
  10. }
        delphi这边为:
  1. var
  2.   pStr: PChar;
  3. begin
  4.   getTest(@pStr);
  5.   ShowMessage(pStr);
  6. end;
        咦,还真可以了。Ok,跟厂家协定好,就这么做。双方很高兴的完成了接口的联调工作。
        可是,我在仔细阅读接口文档一边又一边时,给自己提出了一个问题,将如,明年厂家更换了,更换的这个厂家如果用Delphi写这个DLL,我又不想修改现在的调用程序,那么这个DLL怎么实现?左思又询中,想到了用PPChar来代替char**, 就写出了如下的函数:
  1. function getTest(info: PPChar): Integer;
  2. var
  3.   str: PChar;
  4. begin
  5.   Result := -1;  // 返回错误代码
  6.   try
  7.     str := 'Test';
  8.     // TODO: str业务处理
  9.     Info^ := strAlloc(Length(str) * SizeOf(Char) + 1); // 分配内存空间
  10.     StrCopy(Info^, PChar(str));
  11.     Result := 0;
  12.   except
  13.   end;
  14. end;
        经多次测试,发现这样写非常的成功。我终于安心的关闭了接口文档,宣布接口联调结束。
        可能大家还有疑问,如:为什么分配内存空间时VC和Delphi都要加1了?那是因为需要存储字符串结束符"/0"(其实在上面也找得到答案,见"c[strlen(str)] = 0x00;"这句代码)。
        发现我们做开发的真正做进去了,冠冕堂皇的叫做"举一反三",从工作效率上讲,这叫"没事找事"。得出个名言:"世上本无事,找的人多了,也就有了事"。

C语言双指针的常见用法

鉴于工作经验有限,目前遇到的双指针的用法有如下几种情况,后续工作中如发现有其他的用法,会更新上去。 1、用作函数的返回值,比较常见的是返回分配的堆内存地址。 2、用于申请动态一维数组,只是这个一维数组...
  • CeeLo_Atom
  • CeeLo_Atom
  • 2015年10月30日 10:19
  • 4938

深入理解双指针

转载:http://blog.csdn.net/feiyinzilgd/archive/2010/02/09/5302369.aspx 对于C语言的参数传递都是值传递,当传传递一个指针给函数...
  • h_wlyfw
  • h_wlyfw
  • 2014年03月12日 10:32
  • 1116

面试算法:双指针单向链表的自我复制

一种链表特点是,除了next指向下一个节点外,它还多了一个指针jump,这个指针指向队列中的某一个节点,这个节点可以是当前节点自己,也可以是队列中的其他节点。例如上图,节点0的jump指针指向了最后一...
  • tyler_download
  • tyler_download
  • 2017年01月21日 10:28
  • 336

数组双指针法汇总

指针移动方向:相向夹逼,同向移动 维护的是一个区间还是只是关心指针指向的两个元素 同向移动的、维护一个区间的双指针法即滑动窗口法, 2Sum 两头往中间夹逼的双指针法。指针为什么可以不回退?即为什么可...
  • binling
  • binling
  • 2014年12月14日 17:12
  • 711

双指针扫描

输入一行数字,如果我们把这行数字中的‘5’都看成空格,那么就得到一行用空格分割的若干非负整数(可能有些整数以‘0’开头,这些头部的‘0’应该被忽略掉,除非这个整数就是由若干个‘0’组成的,这时这个整数...
  • liuzhan214
  • liuzhan214
  • 2016年01月23日 15:51
  • 1683

指针和双指针作为函数参数

1. 每个变量都有一个地址和初值,初值可以被改变,这个值的类型可以是int,char,double,float等。 2. 指针是变量,指针变量也有地址和初值,只不过指针变量的值是地址类型。 3. ...
  • ddl2111
  • ddl2111
  • 2016年02月25日 20:25
  • 346

关于链表算法题的双指针

经常能够碰到链表的题,当用一个指针遍历来解决问题的时候,不是无法解决就是效率不佳,典型的就是需要多次遍历且需要额外的存储空间。在这种情况下,可以尝试用两个指针来遍历链表,而两指针遍历链表又可以分为两种...
  • sicofield
  • sicofield
  • 2013年06月01日 20:26
  • 3151

算法入门:双指针法

一、双指针法【例子1】 :求一个有序数组中和=8的下标。=====================================设置两个不同的指针 ,或者头,或者尾。在一个递增的序列中,。根据结果分...
  • qq_29475553
  • qq_29475553
  • 2016年09月08日 10:22
  • 655

算法总结--数组相关】双指针法的常见应用

所谓双指针,指的是在遍历对象的过程中,不是普通的使用单个指针进行访问,而是使用两个相同方向或者相反方向的指针进行扫描,从而达到相应的目的。     换言之,双指针法充分使用了数组有序这一特征,从而在...
  • qq_26222859
  • qq_26222859
  • 2017年03月13日 10:26
  • 230

LeetCode 之K-Sum 问题(个人理解) 双指针大法(总结)

做过leetcode的人都知道, 里面有2sum, 3sum(closest), 4sum等问题, 这些也是面试里面经典的问题, 考察是否能够合理利用排序这个性质, 一步一步得到高效的算法. 经过总结...
  • liutianshx2012
  • liutianshx2012
  • 2015年06月17日 10:29
  • 763
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Delphi双指针使用
举报原因:
原因补充:

(最多只允许输入30个字)