zoukankan      html  css  js  c++  java
  • 使用Delphi声明C++带函数的结构体实战 good

    在小组开发中,应用程序部分采用Delphi7,一些组件使用C++做。在今天将一个动态库的C++接口声明头文件转换为D7的Unit单元时,一切都很顺利,直到遇到下面这样一个另类的东西:

    typedef struct tagRecord
    {
     int val;
     int getvalplus()
     {
      val++;
      return val;
     }
    }TRecord, *PRecord; 

        带函数的结构体!面对这个面目狰狞的家伙,我开始无所适从,狂在GOOGLE、BAIDU里通过关键字“Delphi 带函数的记录类型”、“Delphi C++ 结构体 函数”、“Delphi record function”......结果都是无功而返。

        一边搜索,还一边通过编码测试来寻找问题解决门道。起初我尝试效仿采用函数指针的方式,结果函数体无法实现,更不用说访问结构体其他成员了。

        后面又一次试着采用class而非record类型来声明:

     PRecord = ^TRecord;
      TRecord = class
      public
        val: integer;
        function getvalplus():integer;
      end;     

        在接口部分:function ShowValue(rcd: PRecord):integer;stdcall;external 'Structdll.dll';   

        参数rcd无论声明为PRecord还是Pointer,传递进去之后debug调试出来的值根本就不对,疑似某对象的地址之类的数字。去俺们圈子的技术群里请教高手结果还引来“变态、真贱”的一顿骂,哪儿有这么用的?不吃饱了撑得吗?那你就考虑考虑采用代理模式来迂回解决吧!......这个时候,我几乎绝望了,特别无助,我的印象里,在Win32开发这片沃土里,Delphi和C++本就一脉相承的啊,但面对这个细节的时候我发现原来景色并不是那么美好。

        无奈之下到CSDN社区的Delphi->API板块发帖提问,这时也临近中午,吃了几口面包,吞了两缸凉白开困意来了,撂倒就是一觉......哪知一觉醒来发现有人回帖了,虽然他在D2007上验证通过,但我还是抱着试试看的想法在D7上开始测试。没成想,嘿!果然有效哎!你看看:

        在dll库里的声明(C++):

    typedef struct tagRecord
    {
     int val;
     int getvalplus()
     {
      val++;
      return val;
     }
    }TRecord, *PRecord;

    extern "C" __declspec(dllexport) int __stdcall ShowValue(TRecord *rcd)
    {
     int val = rcd->getvalplus();
     CString ss = _T("");
     ss.Format("Value is:%d", val);
     AfxMessageBox(ss);
     return 0;
    }

        在D7中的声明:

    type
      
    PRecord = ^TRecord;
      TRecord = Object
      
    public
        val: integer;
        function getvalplus():integer;
      end;


    function ShowValue(rcd: PRecord):integer;stdcall;external 'Structdll.dll';

    implementation

    function TRecord.getvalplus():integer;
    begin
      val := val + 1;
      Result := val;
    end;

    在D7中的调用:    

    procedure TfrmMain.Button1Click(Sender: TObject);
    var
      r: TRecord;
      pr: PRecord;
    begin
      r.val := 10;
      pr := @r;
      r.getvalplus;
      ShowMessage(inttostr(r.val));
      ShowValue(pr);
    end;

     

            后记:以前在DOS下,以C/C++为主,Pascal只用过Turbo Pascal4.0,对以后Pascal的版本并不十分了解,今天看了网友housisong的留言,才知道我所谓的新功能--有限栈对象,Delphi中早就有了,如Delphi7.0就可以使用Object关键字定义栈对象,而且比2007的record类型还完善一些,record不能继承,而object对象能够继承,看来我真是孤陋寡闻了!!!

    http://blog.csdn.net/henreash/article/details/25313019
  • 相关阅读:
    MATLAB批量读入图片
    MATLAB小技巧
    Ubuntu下OpenCV不能被某个python版本识别
    切换Ubuntu系统python默认版本的方法
    LoadRunner内部结构(2)
    LoadRunner例子:检查点为参数的一个例子
    LoadRunner中字符串的操作
    LoadRunner脚本实例来验证参数化的取值
    LoadRunner编程之文件的操作
    LoadRunner关联函数的脚本实例--如何操作关联参数
  • 原文地址:https://www.cnblogs.com/findumars/p/5285889.html
Copyright © 2011-2022 走看看