• ZC_C++类函数指针_模拟_Delphi类函数指针_Qt例子


    qt-opensource-windows-x86-msvc2010_opengl-5.3.2.exe

    ZC: “const QString” 作传入参数的时候,不太会弄... 貌似 还是在进行构建等的操作,按照暂时的水平这种情况还不太会弄... 于是 用“QString&”或“QString*”作参数

    ZC: Qt调试 比较麻烦,还是使用 VS2010 来调试 看汇编的...

    1、mainwindows.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    #include <QDebug>
    #include "TClassFuncPtr.h"
    
    void MainWindow::on_pbtnTest01_clicked()
    {
    //*
        CTest test;
    
        void *pFunc = pointer_cast<void*>(&CTest::GetString);
    
        Tcfp_Qs_II cfp;
        cfp.Set(&test, pFunc);
        QString str = cfp.Call(1, 3);
        qDebug() << str;
    //*/
    /*
        CTest test;
        QString str = test.GetString(1, 3);
    //*/
    }
    
    void MainWindow::on_pbtnTest02_clicked()
    {
        QString str = "33";
    //*
        CTest test;
    
        void *pFunc = pointer_cast<void*>(&CTest::GetIntFromString);
    
        Tcfp_I_CQs cfp;
        cfp.Set(&test, pFunc);
        int iRtn = cfp.Call(str);
        qDebug() << str;
    //*/
    /*
        CTest test;
        int iRtn = test.GetIntFromString(str);
        qDebug() << iRtn;
    //*/
    }
    
    void MainWindow::on_pbtnTest03_clicked()
    {
        QString str = "33";
    //*
        CTest test;
    
        void *pFunc = pointer_cast<void*>(&CTest::GetIntFromString01);
    
        Tcfp_I_Qs cfp;
        cfp.Set(&test, pFunc);
        int iRtn = cfp.Call(str);
        qDebug() << iRtn;
    }
    
    void MainWindow::on_pbtnTest04_clicked()
    {
        QString str = "330";
    //*
        CTest test;
    
        void *pFunc = pointer_cast<void*>(&CTest::GetIntFromString02);
    
        Tcfp_I_Qsp cfp;
        cfp.Set(&test, pFunc);
        int iRtn = cfp.Call(&str);
        qDebug() << iRtn;
    }

    2、TClassFuncPtr.h

    #ifndef TCLASSFUNCPTR_H
    #define TCLASSFUNCPTR_H
    
    #include <QString>
    
    // ZC: 子类 命名规则:“Tcfp_返回值类型_各个传入参数类型()”
    
    
    class TClassFuncPtr
    {
    public:
        TClassFuncPtr()
        {
            FpObj = NULL;
            FpFunc = NULL;
        }
    
    protected:
        void* FpObj;    // ZC: 对象指针
        void* FpFunc;    // ZC: 类函数的 函数地址(统一使用stdcall调用约定,函数传参/调用的时候 方便一点)
    
    public:
        void Set(void *_pObj, void *_pFunc)
        {
            FpObj = _pObj;
            FpFunc = _pFunc;
        }
    
        bool IsValid()
        {
            return ( (FpObj != NULL) && (FpFunc != NULL) );
        }
    };
    
    
    
    
    class Tcfp_Qs_II :public TClassFuncPtr
    {
    public:
        QString __stdcall Call(int _i, int _j);
    };
    
    class Tcfp_I_CQs :public TClassFuncPtr
    {
    public:
        int __stdcall Call(const QString _str);
    };
    
    class Tcfp_I_Qs :public TClassFuncPtr
    {
    public:
        int __stdcall Call(QString &_str);
    };
    
    class Tcfp_I_Qsp :public TClassFuncPtr
    {
    public:
        int __stdcall Call(QString *_pstr);
    };
    
    // ZC: 获取 类函数指针(地址)
    template<typename dst_type,typename src_type>
    dst_type pointer_cast(src_type src)
    {
        return *static_cast<dst_type*>(static_cast<void*>(&src));
    }
    #endif // TCLASSFUNCPTR_H
    
    
    class CTest
    {
    private:
        int Fi;
    public:
        QString __stdcall GetString(int _i, int _j);
    
        int __stdcall GetIntFromString(const QString _str);
        int __stdcall GetIntFromString01(QString &_str);
        int __stdcall GetIntFromString02(QString *_pstr);
    };

    3、TClassFuncPtr.cpp

    #include "TClassFuncPtr.h"
    
    
    
    #pragma optimize( "", off )
    QString __stdcall Tcfp_Qs_II::Call(int _i, int _j)
    {
        if (IsValid())
        {
            _asm
            {
                push _j
                push _i
                mov eax,dword ptr [ebp+0xC]
                push eax
                mov eax,[this] // ZC: 貌似和语句“mov eax,this”是一样的效果...
                // [eax] ==> FpObj
                // [eax+4] ==> FpFunc
                push [eax]
                call [eax+4]
            }
        }
    }
    
    
    int __stdcall Tcfp_I_CQs::Call(const QString _str)
    {
        if (IsValid())
        {
            void *p = (void*)&_str;
            _asm
            {
                push p
                mov eax,[this] // ZC: 貌似和语句“mov eax,this”是一样的效果...
                // [eax] ==> FpObj
                // [eax+4] ==> FpFunc
                push [eax]
                call [eax+4]
            }
        }
    }
    
    int __stdcall Tcfp_I_Qs::Call(QString &_str)
    {
        if (IsValid())
        {
            _asm
            {
                mov eax,[ebp+0xC]
                push eax
                mov eax,[this] // ZC: 貌似和语句“mov eax,this”是一样的效果...
                // [eax] ==> FpObj
                // [eax+4] ==> FpFunc
                push [eax]
                call [eax+4]
            }
        }
    }
    
    int __stdcall Tcfp_I_Qsp::Call(QString *_pstr)
    {
        if (IsValid())
        {
            _asm
            {
                mov eax,[ebp+0xC]
                push eax
                mov eax,[this] // ZC: 貌似和语句“mov eax,this”是一样的效果...
                // [eax] ==> FpObj
                // [eax+4] ==> FpFunc
                push [eax]
                call [eax+4]
            }
        }
    }
    
    //#pragma optimize( "", on )
    
    //#pragma optimize( "", off )
    QString __stdcall CTest::GetString(int _i, int _j)
    {
        __asm
        {
            mov eax,eax
            mov eax,eax
            mov eax,eax
        }
        Fi = 10;
        return ( QString::number(_i)+","+QString::number(_j)+","+QString::number(Fi) );
    }
    
    int __stdcall CTest::GetIntFromString(const QString _str)
    {
        return _str.toInt();
    }
    
    int __stdcall CTest::GetIntFromString01(QString &_str)
    {
        return _str.toInt();
    }
    
    int __stdcall CTest::GetIntFromString02(QString *_pstr)
    {
        return (*_pstr).toInt();
    }
    
    #pragma optimize( "", on )

    4、mainwindow.ui

      4.1、

      4.2、

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>MainWindow</class>
     <widget class="QMainWindow" name="MainWindow">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>400</width>
        <height>300</height>
       </rect>
      </property>
      <property name="windowTitle">
       <string>MainWindow</string>
      </property>
      <widget class="QWidget" name="centralWidget">
       <widget class="QPushButton" name="pbtnTest01">
        <property name="geometry">
         <rect>
          <x>50</x>
          <y>40</y>
          <width>75</width>
          <height>23</height>
         </rect>
        </property>
        <property name="text">
         <string>Test01</string>
        </property>
       </widget>
       <widget class="QPushButton" name="pbtnTest02">
        <property name="geometry">
         <rect>
          <x>50</x>
          <y>70</y>
          <width>75</width>
          <height>23</height>
         </rect>
        </property>
        <property name="text">
         <string>Test02</string>
        </property>
       </widget>
       <widget class="QPushButton" name="pbtnTest03">
        <property name="geometry">
         <rect>
          <x>50</x>
          <y>100</y>
          <width>75</width>
          <height>23</height>
         </rect>
        </property>
        <property name="text">
         <string>Test03</string>
        </property>
       </widget>
       <widget class="QPushButton" name="pbtnTest04">
        <property name="geometry">
         <rect>
          <x>50</x>
          <y>130</y>
          <width>75</width>
          <height>23</height>
         </rect>
        </property>
        <property name="text">
         <string>Test04</string>
        </property>
       </widget>
      </widget>
      <widget class="QMenuBar" name="menuBar">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>400</width>
         <height>17</height>
        </rect>
       </property>
      </widget>
      <widget class="QToolBar" name="mainToolBar">
       <attribute name="toolBarArea">
        <enum>TopToolBarArea</enum>
       </attribute>
       <attribute name="toolBarBreak">
        <bool>false</bool>
       </attribute>
      </widget>
      <widget class="QStatusBar" name="statusBar"/>
     </widget>
     <layoutdefault spacing="6" margin="11"/>
     <resources/>
     <connections/>
    </ui>

    5、

  • 相关阅读:
    浅谈Java 8的新特性和使用场景
    Oracle下通过EXPDP导出某用户下的所有表,实例
    官网下载I.MX6参考手册
    TFTP服务开启
    二、 U-Boot 命令使用
    CP15协处理器
    Linux内核配置Kconfig语法
    M.2接口是如何辨别插入的SSD是SATA协议还是NVME协议?
    SSH 服务开启
    一 、 UBOOT简介
  • 原文地址:https://www.cnblogs.com/cppskill/p/6276740.html
Copyright © 2020-2023  润新知