精华内容
下载资源
问答
  • C++消息机制

    2011-12-25 21:32:11
    C++消息机制
  • C++消息机制,两个exe之间的通讯

    千次阅读 2019-06-10 10:36:54
    1.定义消息 static const UINT Msg_Test = ::RegisterWindowMessage(MSG_TEST); 2.注册消息 static const UINT MsgEapTestStart = ::RegisterWindowMessage(EAP_TEST_START); 3.发送消息 ::SendNotifyMessage(HWND_...

    1.定义消息
    static const UINT Msg_Test = ::RegisterWindowMessage(MSG_TEST);

    2.注册消息
    static const UINT MsgEapTestStart = ::RegisterWindowMessage(EAP_TEST_START);

    3.发送消息
    ::SendNotifyMessage(HWND_BROADCAST,MsgEapTestStart,0,0);

    展开全文
  • C++ 消息映射机制深度探索
  • 简介:完全不是MFC中的消息映射机制,即没有用到MFC中的一点消息机制。 但原理却是一样的,是个麻雀虽小五脏俱全的消息映射原理,简单实现了 SendMail(APPMSG_START, NULL, APPID_TEST1, 0)的源代码,经测试成功。 ...
  • c++消息机制(一)

    千次阅读 2016-08-30 14:04:28
    今天研究c++消息机制是遇到两个参数不是很明白 查了下资料 记录下(以下都是我个人理解,错误请帮忙指正): LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam, LPARAM lParam); 这是一个向指定的窗口...

    今天研究c++消息机制是遇到两个参数不是很明白 查了下资料 记录下(以下都是我个人理解,错误请帮忙指正):

    LRESULT SendMessageHWND hWnd,UINT Msg,WPARAM wParam, LPARAM lParam);

    这是一个向指定的窗口发送指定消息的函数

    HWND hWnd 这个参数是窗口的句柄,相当于id的玩意 不难理解

    UINT Msg 这个是要发送的消息 如:WM_CLOSE,WM_SETTEXT。。。。。。。好多

    WPARAM wParamLPARAM lParam这两个参数不是很陌生 下面也是我看其他的资料得到的理解

     

    Windows的消息必须参考帮助文件才能知道具体的含义。如果是你定义的消息,愿意怎么使这两个参数都行。但是习惯上,我们愿意使用LPARAM传 递地址,而WPARAM传递其他参数。”

    接下来谈谈什么是消息机制:系统将会维护一个或多个消息队列,所有产生的消息都回被放入或是插入队列中。系统会在队列中取出每一条消息,根据消息的接收句柄而将该消息发送给拥有该窗口的程序的消息循环。每一个运行的程序都有自己的消息循环,在循环中得到属于自己的消息并根据接收窗口的句柄调用相应的窗口过程。而在没有消息时消息循环就将控制权交给系统所以Windows可以同时进行多个任务。下面的伪代码演示了消息循环的用法:

     

     

    例如:主程序MyDlg.cpp

    1.自定义消息:#define WM_TRAY WM_USER 100

    2.函数原形:afx_msg LRESULT OnTrayNotify(WPARAM wParam,LPARAM lParam);

    3.消息映射:ON_MESSAGE(WM_TRAY,OnTrayNotify)

    4.原函数:

    LRESULT CMyDlg::OnTrayNotify(WPARAM wParam,LPARAM lParam)

    {

    return m_tray.OnTrayNotify(wParam,lParam);

    }

     

    上面程序呢 主要过程是这样 自定义了一个消息WM_TRAY 

    再创建一个函数OnTrayNotify 

    然后将消息和函数绑定在一起ON_MESSAGE(WM_TRAY,OnTrayNotify)

    每当接受这个消息时就运行函数

    WPARAM wParam,LPARAM lParam这两个参数就是消息附带的参数跟着消息一起传递过来


    在Win32 SDK中消息本身是作为一个结构体记录传递给应用程序的,这个记录中包含了消息的类型以及其他信息。这个记录类型叫做MSG,它在window中是这样声明的:
    typedef struct tagMSG { // msg
    HWND hwnd; //窗口句柄
    UINT message; //消息常量标识符
    WPARAM wParam; //32位消息的特定附加信息,具体表示什么处决于message
    LPARAM lParam; //32位消息的特定附加信息,具体表示什么处决于message
    DWORD time; //消息创建时的时间
    POINT pt; //消息创建时的鼠标位置
    } MSG;

    hwnd 接收消息的32位窗口句柄。窗口可以是任何类型的屏幕对象,因为Win32能够维护大多数可视对象的句柄(窗口、对话框、按钮、编辑框等)。


    message 用于区别其他消息的常量值,这些常量可以是Windows单元中预定义的常量,也可以是自定义的常量。


    wParam 通常是一个与消息有关的常量值,也可能是窗口或控件的句柄。 lParam 通常是一个指向内存中数据的指针。由于wParam,lParam和指针都是32位的,需要时可以强制类型转换。具体表示什么,与message相关,他们是事先定义好的。


    如果自定义消息:#define WM_MYMESSAGE WM_USER+100,需确定wParam,lParam的意义 (假设wParam=0时发送数据,wParam=1时接收数据,lParam为CMyClass* 指针,指向一个CMyClass对象,准备要发送的数据或接收数据 发送WM_MYMESSAGE时 SendMessage(hwnd,WM_MYMESSAGE,0,pMyClassObject) 接收消息的窗口,接收WM_MYMESSAGE中(CMyClass*)lParam参数即pMyClassObject传过来的数据



    展开全文
  • C++Builder消息处理机制

    2012-12-11 16:40:13
    C++Builder消息处理机制
  • C++反射机制

    2012-09-29 11:20:31
    C++反射机制
  • 深入Windows内核——C++中的消息机制

    万次阅读 多人点赞 2015-06-14 21:31:37
    《编程思想之消息机制》一文中我们讲了消息的相关概念和消息机制的模拟,本文将进一步聊聊C++中的消息机制。从简单例子探析核心原理在讲之前,我们先看一个简单例子:创建一个窗口和两个按钮,用来控制窗口的背景...

    编程思想之消息机制》一文中我们讲了消息的相关概念和消息机制的模拟,本文将进一步聊聊C++中的消息机制。


    从简单例子探析核心原理

    在讲之前,我们先看一个简单例子:创建一个窗口和两个按钮,用来控制窗口的背景颜色。其效果如下:

    白色窗口 灰色窗口
    图 2 :效果图

    Win32Test.h

    #pragma once
    
    #include <windows.h>
    #include <atltypes.h>
    #include <tchar.h>
    
    //资源ID
    #define ID_BUTTON_DRAW      1000
    #define ID_BUTTON_SWEEP     1001
    
    // 注册窗口类
    ATOM AppRegisterClass(HINSTANCE hInstance);
    // 初始化窗口
    BOOL InitInstance(HINSTANCE, int);
    // 消息处理函数(又叫窗口过程)
    LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
    // (白色背景)按钮事件
    void OnButtonWhite();
    // (灰色背景)按钮事件
    void OnButtonGray();
    // 绘制事件
    void OnDraw(HDC hdc);

    Win32Test.cpp

    
    #include "stdafx.h"
    #include "Win32Test.h"
    
    
    //字符数组长度
    #define MAX_LOADSTRING 100
    
    //全局变量
    HINSTANCE hInst;                                            // 当前实例
    TCHAR g_szTitle[MAX_LOADSTRING] = TEXT("Message process");  // 窗口标题
    TCHAR g_szWindowClass[MAX_LOADSTRING] = TEXT("AppTest");    // 窗口类的名称
    HWND g_hWnd;                                                // 窗口句柄
    bool g_bWhite = false;                                      // 是否为白色背景
    
    //WinMain入口函数
    int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
    {
        UNREFERENCED_PARAMETER(hPrevInstance);
        UNREFERENCED_PARAMETER(lpCmdLine);
        // 注册窗口类
        if(!AppRegisterClass(hInstance))
        {
             return (FALSE);
        }
        // 初始化应用程序窗口
        if (!InitInstance (hInstance, nCmdShow))
        {
            return FALSE;
        }
    
        // 消息循环
        MSG msg;
        while (GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        return (int) msg.wParam;
    }
    
    
    
    // 注册窗口类
    ATOM AppRegisterClass(HINSTANCE hInstance)
    {
        WNDCLASSEX wcex;
        wcex.cbSize = sizeof(WNDCLASSEX);
        wcex.style          = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc    = WndProc;
        wcex.cbClsExtra     = 0;
        wcex.cbWndExtra     = 0;
        wcex.hInstance      = hInstance;
        wcex.hIcon          = LoadIcon(NULL, IDI_APPLICATION);
        wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
        wcex.lpszMenuName   = NULL;
        wcex.lpszClassName  = g_szWindowClass;
        wcex.hIconSm        = NULL;
    
        return RegisterClassEx(&wcex);
    }
    
    
    
    // 保存实例化句柄并创建主窗口
    BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    {  
       hInst = hInstance; // 保存handle到全局变量
       g_hWnd = CreateWindow(g_szWindowClass, g_szTitle, WS_OVERLAPPEDWINDOW, 0, 0, 400, 300, NULL, NULL, hInstance, NULL);
       // 创建按钮
       HWND hBtWhite = CreateWindowEx(0, L"Button", L"白色", WS_CHILD | WS_VISIBLE | BS_TEXT, 100, 100, 50, 20, g_hWnd, (HMENU)ID_BUTTON_DRAW, hInst, NULL);
       HWND hBtGray = CreateWindowEx(0, L"Button", L"灰色", WS_CHILD | WS_VISIBLE | BS_CENTER, 250, 100, 50, 20, g_hWnd, (HMENU)ID_BUTTON_SWEEP, hInst, NULL);
    
       if (!g_hWnd)
       {
          return FALSE;
       }
       ShowWindow(g_hWnd, nCmdShow);
       UpdateWindow(g_hWnd);
    
       return TRUE;
    }
    
    
    
    // (窗口)消息处理
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        int wmId, wmEvent;
        PAINTSTRUCT ps;
        HDC hdc;
    
        switch (message)
        {
        case WM_COMMAND:
            wmId    = LOWORD(wParam);
            //wmEvent = HIWORD(wParam);
    
            switch (wmId)
            {
            case ID_BUTTON_DRAW:
                OnButtonWhite();
                break;
            case ID_BUTTON_SWEEP:
                OnButtonGray();
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
            break;
        case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);
            OnDraw(hdc);
            EndPaint(hWnd, &ps);
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        return 0;
    }
    
    
    
    //事件处理
    
    //按下hBtWhite时的事件
    void OnButtonWhite()
    {
        g_bWhite = true;
        InvalidateRect(g_hWnd, NULL, FALSE);    //刷新窗口
    }
    
    //按下hBtGray时的事件
    void OnButtonGray()
    {
        g_bWhite = false;
        InvalidateRect(g_hWnd, NULL, FALSE);    //刷新窗口
    }
    
    //绘制事件(每次刷新时重新绘制图像)
    void OnDraw(HDC hdc)
    {   
        POINT oldPoint;
        SetViewportOrgEx(hdc, 0, 0, &oldPoint);
        RECT rcView;
        GetWindowRect(g_hWnd, &rcView); // 获得句柄的画布大小
        HBRUSH hbrWhite = (HBRUSH)GetStockObject(WHITE_BRUSH);
        HBRUSH hbrGray = (HBRUSH)GetStockObject(GRAY_BRUSH);
        if (g_bWhite)
        {
            FillRect(hdc, &rcView, hbrWhite);
        } else
        {
            FillRect(hdc, &rcView, hbrGray);
        }
        SetViewportOrgEx(hdc, oldPoint.x, oldPoint.y, NULL);
    }
    

    在上面这个例子中,消息的流经过程如下:

    消息的流经过程
    图 3 :消息的流经过程

    这与《 编程思想之消息机制》中图1(消息机制原理)是相吻合的,这就是Windows消息机制的核心部分,也是Windows API开发的核心部分。 Windows系统和Windows下的程序都是以消息为基础,以事件为驱动。
    RegisterClassEx的作用是注册一个窗口,在调用CreateWindow创建一个窗口前必须向windows系统注册获惟一的标识。

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    这个while循环就是消息循环,不断地从消息队列中获取消息,并通过DispatchMessage(&msg)将消息分发出去。消息队列是在Windows操作系统中定义的(我们无法看到对应定义的代码),对于每一个正在执行的Windows应用程序,系统为其建立一个“消息队列”,即应用程序队列,用来存放该程序可能创建的各种窗口的消息。DispatchMessage会将消息传给窗口函数(即消息处理函数)去处理,也就是WndProc函数。WndProc是一个回调函数,在注册窗口时通过wcex.lpfnWndProc将其传给了操作系统,所以DispatchMessage分发消息后,操作系统会调用窗口函数(WndProc)去处理消息。关于回调函数可参考:回调函数。
    每一个窗口都应该有一个函数负责消息处理,程序员必须负责设计这个所谓的窗口函数WndProc。LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 中的四个参数就是消息的相关信息(消息来自的句柄、消息类型等),函数中通过switch/case根据不同的消息类型分别进行不同的处理。在收到相应类型的消息之后,可调用相应的函数去处理,如OnButtonWhite、OnButtonGray、OnDraw,这就是事件处理的雏形。 在default中调用了DefWindowProc,DefWindowProc是操作系统定义的默认消息处理函数,这是因为所有的消息都必须被处理,应用程序不处理的消息需要交给操作系统处理。


    消息的定义和类型

    Windows消息都以WM_为前缀,意思是”Windows Message”,如WM_CREATE、WM_PAINT等。消息的定义如下:

    typedef struct tagMsg
    {   
        HWND    hwnd;           //接受该消息的窗口句柄
        UINT    message;        //消息常量标识符,也就是我们通常所说的消息号
        WPARAM  wParam;         //32位消息的特定附加信息,确切含义依赖于消息值
        LPARAM  lParam;         //32位消息的特定附加信息,确切含义依赖于消息值
        DWORD   time;           //消息创建时的时间
        POINT   pt;             //消息创建时的鼠标/光标在屏幕坐标系中的位置
    }MSG;

    消息主要有三种类型:
    1. 命令消息(WM_COMMAND):命令消息是程序员需要程序做某些操作的命令。凡UI对象产生的消息都是这种命令消息,可能来自菜单、加速键或工具栏按钮等,都以WM_COMMAND呈现。
    2. 标准窗口消息:除WM_COMMAND之处,任何以WM_开头的消息都是这一类。标准窗口消息是系统中最为常见的消息,它是指由操作系统和控制其他窗口的窗口所使用的消息。例如CreateWindow、DestroyWindow和MoveWindow等都会激发窗口消息,以及鼠标移动、点击,键盘输入都是属于这种消息。
    3. Notification:这种消息由控件产生,为的是向其父窗口(通常是对话框窗口)通知某种情况。当一个窗口内的子控件发生了一些事情,而这些是需要通知父窗口的,此刻它就上场啦。通知消息只适用于标准的窗口控件如按钮、列表框、组合框、编辑框,以及Windows公共控件如树状视图、列表视图等。

    队列消息和非队列消息

    Windows中有一个系统消息队列,对于每一个正在执行的Windows应用程序,系统为其建立一个“消息队列”,即应用程序队列,用来存放该程序可能创建的各种窗口的消息。
    (1)队列消息(Queued Messages)
    消息会先保存在消息队列中,通过消息循环从消息队列中获取消息并分发到各窗口函数去处理,如鼠标、键盘消息就属于这类消息。
    (2)非队列消息(NonQueued Messages)
    就是消息会直接发送到窗口函数处理,而不经过消息队列。 如: WM_ACTIVATE, WM_SETFOCUS, WM_SETCURSOR, WM_WINDOWPOSCHANGED就属于此类。

    PostMessage与SendMessage的区别

    PostMessage发送的消息是队列消息,它会把消息Post到消息队列中; SendMessage发送的消息是非队列消息, 被直接送到窗口过程处理,等消息被处理后才返回。

    这里写图片描述
    图 4 :消息队列示意图

    为证明这一过程,我们可以改动一下上面的这个例子。
    1.在Win32Test.h中添加ID_BUTTON_TEST的定义

    #define ID_BUTTON_TEST      1002

    2.在OnButtonWhite中分别用SendMessage和PostMessage发送消息
    //按下hBtWhite时的事件

    void OnButtonWhite()
    {
        g_bWhite = true;
        InvalidateRect(g_hWnd, NULL, FALSE);    //刷新窗口
        SendMessage(g_hWnd, WM_COMMAND, ID_BUTTON_TEST, 0);
        //PostMessage(g_hWnd, WM_COMMAND, ID_BUTTON_TEST, 0);
    }

    3.在消息循环中增加ID_BUTTON_TEST的判断

    while (GetMessage(&msg, NULL, 0, 0))
        {
            if (LOWORD(msg.wParam) == ID_BUTTON_TEST)
            {
                OutputDebugString(L"This is a ID_BUTTON_TEST message.");    // [BreakPoint1]
            }
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

    4.在窗口处理函数WndProc增加ID_BUTTON_TEST的判断

    case ID_BUTTON_TEST:
        {
            OutputDebugString(L"This is a ID_BUTTON_TEST message.");        // [BreakPoint2]
        }
        break;
    case ID_BUTTON_DRAW:
        OnButtonWhite();
        break;
    case ID_BUTTON_SWEEP:
        OnButtonGray();
        break;

    用断点调试的方式我们发现,用SendMessage发送的ID_BUTTON_TEST消息只会进入BreakPoint2,而PostMessage发送的ID_BUTTON_TEST会进入到BreakPoint1和BreakPoint2。



    如果您有什么疑惑和想法,请在评论处给予反馈,您的反馈就是最好的测评师!由于本人技术和能力有限,如果本博文有错误或不足之处,敬请谅解并给出您宝贵的建议!




    ========================编程思想系列文章回顾========================
    编程思想之消息机制
    编程思想之日志记录
    编程思想之异常处理
    编程思想之正则表达式
    编程思想之迭代器
    编程思想之递归
    编程思想之回调

    展开全文
  • C++ Builder中消息机制的研究与应用技巧
  • C++Builder消息处理机制.pdf,希望你能喜欢。
  • [培训]C++异常机制

    2016-03-25 20:28:50
    [培训]C++异常机制
  • C++反射机制实现

    2014-11-12 11:56:53
    C++反射机制实现,根据类名字符串创建该类的实例;根据类的属性字符串来设置属性;
  • 消息驱动机制是Windows操作系统的根本,模态对话框消息处理又是不同于一般消息处理的特殊形式。通过分析这种消息机制的原理,可用来处理类似的程序设计要求。
  • 主要介绍了C++ 反射机制详解及实例代码的相关资料,需要的朋友可以参考下
  • C++RAII机制

    万次阅读 多人点赞 2019-06-25 18:16:34
    RAII是Resource Acquisition Is Initialization(wiki上面翻译成 “资源获取就是初始化”)的简称,是C++语言的一种管理资源、避免泄漏的惯用法。利用的就是C++构造的对象最终会被销毁的原则。RAII的做法是使用一个...

    什么是RAII?

    RAII是Resource Acquisition Is Initialization(wiki上面翻译成 “资源获取就是初始化”)的简称,是C++语言的一种管理资源、避免泄漏的惯用法。利用的就是C++构造的对象最终会被销毁的原则。RAII的做法是使用一个对象,在其构造时获取对应的资源,在对象生命期内控制对资源的访问,使之始终保持有效,最后在对象析构的时候,释放构造时获取的资源。

    为什么要使用RAII?

    上面说到RAII是用来管理资源、避免资源泄漏的方法。那么,用了这么久了,也写了这么多程序了,口头上经常会说资源,那么资源是如何定义的?在计算机系统中,资源是数量有限且对系统正常运行具有一定作用的元素。比如:网络套接字、互斥锁、文件句柄和内存等等,它们属于系统资源。由于系统的资源是有限的,就好比自然界的石油,铁矿一样,不是取之不尽,用之不竭的,所以,我们在编程使用系统资源时,都必须遵循一个步骤:
    1 申请资源;
    2 使用资源;
    3 释放资源。
    第一步和第三步缺一不可,因为资源必须要申请才能使用的,使用完成以后,必须要释放,如果不释放的话,就会造成资源泄漏。

    一个最简单的例子:

    #include <iostream> 
    
    using namespace std; 
    
    int main() 
    
    { 
        int *testArray = new int [10]; 
        // Here, you can use the array 
        delete [] testArray; 
        testArray = NULL ; 
        return 0; 
    }

    小结:
    但是如果程序很复杂的时候,需要为所有的new 分配的内存delete掉,导致极度臃肿,效率下降,更可怕的是,程序的可理解性和可维护性明显降低了,当操作增多时,处理资源释放的代码就会越来越多,越来越乱。如果某一个操作发生了异常而导致释放资源的语句没有被调用,怎么办?这个时候,RAII机制就可以派上用场了。

    如何使用RAII?

    当我们在一个函数内部使用局部变量,当退出了这个局部变量的作用域时,这个变量也就别销毁了;当这个变量是类对象时,这个时候,就会自动调用这个类的析构函数,而这一切都是自动发生的,不要程序员显示的去调用完成。这个也太好了,RAII就是这样去完成的。

    由于系统的资源不具有自动释放的功能,而C++中的类具有自动调用析构函数的功能。如果把资源用类进行封装起来,对资源操作都封装在类的内部,在析构函数中进行释放资源。当定义的局部变量的生命结束时,它的析构函数就会自动的被调用,如此,就不用程序员显示的去调用释放资源的操作了。

    使用RAII 机制的代码:

    #include <iostream> 
    using namespace std; 
    
    class ArrayOperation 
    { 
    public : 
        ArrayOperation() 
        { 
            m_Array = new int [10]; 
        } 
    
        void InitArray() 
        { 
            for (int i = 0; i < 10; ++i) 
            { 
                *(m_Array + i) = i; 
            } 
        } 
    
        void ShowArray() 
        { 
            for (int i = 0; i <10; ++i) 
            { 
                cout<<m_Array[i]<<endl; 
            } 
        } 
    
        ~ArrayOperation() 
        { 
            cout<< "~ArrayOperation is called" <<endl; 
            if (m_Array != NULL ) 
            { 
                delete[] m_Array;  
                m_Array = NULL ; 
            } 
        } 
    
    private : 
        int *m_Array; 
    }; 
    
    bool OperationA(); 
    bool OperationB(); 
    
    int main() 
    { 
        ArrayOperation arrayOp; 
        arrayOp.InitArray(); 
        arrayOp.ShowArray(); 
        return 0;
    }

    上面这个例子没有多大的实际意义,只是为了说明RAII的机制问题。下面说一个具有实际意义的例子:

    template<class... _Mutexes>
    	class lock_guard
    	{	// class with destructor that unlocks mutexes
    public:
    	explicit lock_guard(_Mutexes&... _Mtxes)
    		: _MyMutexes(_Mtxes...)
    		{	// construct and lock
    		_STD lock(_Mtxes...);
    		}
    
    	lock_guard(_Mutexes&... _Mtxes, adopt_lock_t)
    		: _MyMutexes(_Mtxes...)
    		{	// construct but don't lock
    		}
    
    	~lock_guard() _NOEXCEPT
    		{	// unlock all
    		_For_each_tuple_element(
    			_MyMutexes,
    			[](auto& _Mutex) _NOEXCEPT { _Mutex.unlock(); });
    		}
    
    	lock_guard(const lock_guard&) = delete;
    	lock_guard& operator=(const lock_guard&) = delete;
    private:
    	tuple<_Mutexes&...> _MyMutexes;
    	};

    在使用多线程时,经常会涉及到共享数据的问题,C++中通过实例化std::mutex创建互斥量,通过调用成员函数lock()进行上锁,unlock()进行解锁。不过这意味着必须记住在每个函数出口都要去调用unlock(),也包括异常的情况,这非常麻烦,而且不易管理。C++标准库为互斥量提供了一个RAII语法的模板类std::lock_guard,其会在构造函数的时候提供已锁的互斥量,并在析构的时候进行解锁,从而保证了一个已锁的互斥量总是会被正确的解锁。上面的代码正式<mutex>>头文件中的源码,其中还使用到很多C++11的特性,比如delete/noexcept等,有兴趣的同学可以查一下。

    文章参考:https://www.jianshu.com/p/b7ffe79498be

    展开全文
  • C++ windows消息机制和入口函数

    千次阅读 2017-10-29 21:57:03
    消息的结构体 //消息的结构体 typedef struct tagMSG { // msg HWND hwnd;//窗口句柄 UINT message;//无符号整型 不同的消息被定义为宏WM_CHAR等。 WPARAM wParam;//WPARAM整型 记录消息的附加参数 LPARAM ...
  • Lua C++交互机制

    千次阅读 2017-08-16 16:13:46
    一、Lua与C++的交互机制——Lua堆栈1)交互机制Lua和C++ 的交互机制的基础在于Lua提供了一个虚拟栈,C++ 和Lua之间的所有类型的数据交换都通过这个栈完成 栈中每个元素都能保存任何类型的Lua值(实际上Lua的任何类型...
  • C++Event机制的简单实现
  • C++异常机制详解

    千次阅读 多人点赞 2018-06-02 10:33:51
    阅读目录C++异常机制概述throw 关键字异常对象catch 关键字栈展开、RAII异常机制与构造函数异常机制与析构函数noexcept修饰符与noexcept操作符异常处理的性能分析&amp;amp;nbsp;正文回到顶部C++异常机制概述 ...
  • 简单学习c++异常机制

    千次阅读 2019-08-11 22:16:36
    c++异常机制是跨函数的,且必须处理 XXX fun1(int x) { throw x; //抛出异常n'g } XXX fun2() { fun1(0); } XXX fun3() { try //尝试捕获大括号内代码的异常 { fun2(); } catch(int e) //异常时根据类型...
  • C++反射机制的实现

    万次阅读 多人点赞 2016-06-20 10:03:26
    Java中有天然的反射机制,因为Java本身就是半编译语言,很多东西可以在运行时来做,但是c++就不同了。要建立c++的反射机制,就需要登记每个类名与对象的对应关系。 1.前言 在实际的项目中,听到师兄说C++中用到了...
  • C++消息队列

    2015-01-12 15:43:00
    自己写的C++消息队列类,下载可运行,经大量的测试,现在已经用在各种项目中
  • C++ Binder机制学习

    千次阅读 2018-11-08 22:58:15
    Binder机制的核心实际上和Android中的Handler发送消息机制很像,在Binder中负责发消息的是继承了BpInterface的子类,负责处理消息的是BnInterface的子类 发送消息的具体函数是 remote()-&amp;amp;amp;amp;amp;...
  • 讨论了 C++反射机制的实现问题,介绍了反射机制的概念和分类,比较了向 C++添加反射机制的可能性和方式,提出并分析了一 种基于宏定义、模板和泛型机制C++反射机制实现手段
  • C++ Rall机制详解

    万次阅读 2017-04-04 22:47:31
    RAII 是 resource acquisition is initialization 的缩写,意为“资源获取即初始化”。它是 C++ 之父 Bjarne Stroustrup 提出的设计理念,其核心是把资源和对象的生命周期绑定,对象创建...那么到底什么是 RALL 机制
  • .Net 环境下C# 通过托管C++调用本地C++ Dll文件,其中CLI/C++工程里的主类实现了C#写好的接口,C#使用反射机制实现C++的方法集,非常经典的例子,与大家分享
  • C++模板机制

    千次阅读 2014-02-12 18:46:37
    对于执行功能都相同的函数,只是参数类型和返回值类型不同,那么我们可以利用C++的模板机制只需要写一套代码。模板是实现代码重用机制的一种工具,可以大幅度提高程序设计的效率。模板分为函数模板和类模板。 ...
  • Person Employee Person* Employee
  • C++编程中的消息机制

    千次阅读 2011-08-27 16:34:38
    消息映射: BEGIN_MESSAGE_MAP()和END_MESSAGE_MAP()宏定义这个消息映射的边界。 BEGIN_MESSAGE_MAP()宏有两个参数,第一个参数为定义消息映射的当前类名,第二个参数提供一个到该基类的连接,以查找消息处理程序...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 378,656
精华内容 151,462
关键字:

c++消息机制

c++ 订阅