精华内容
下载资源
问答
  • vc 共享内存 例子源代码.visual c++
  • 学习共享内存的好东西,我开始学的时候看的这个
  • VC共享内存

    2013-08-01 21:20:55
    本人自己封装的共享内存类,可以拿来直接使用,代码注释详细,使用说明也很详细。
  • 最近做的项目中,由用户双击启动的应用创建了共享内存,调用CreateFileMapping,按百度到的方式,发现在PHP以服务启动(运行在SYSTEM用户下)无法访问到该共享内存的内容,数值都是0. 后几经百度,发现确实是有命名...

    最近做的项目中,由用户双击启动的应用创建了共享内存,调用CreateFileMapping,按百度到的方式,发现在PHP以服务启动(运行在SYSTEM用户下)无法访问到该共享内存的内容,数值都是0.
    后几经百度,发现确实是有命名空间的问题,正确代码如下:

    CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 1024, “Global\SharedMemName”);
    注意这里最关键的是"Global\SharedMemName"里的Global,代表全局空间,带有这个全局空间的共享内存可以被所有用户或服务访问,不然就算PHP运行在相同用户下,但以服务方式启动时仍然无法访问到。
    典型代码粘贴如下:

    m_hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, memSize, ZNDN_CLOUD_SHARED_MAP);
    	if (NULL == m_hFileMap)
    	{
    		AfxMessageBox("创建主体共享内存失败 CreateFileMapping!");
    		return -2;
    	}
    	if (GetLastError() == ERROR_ALREADY_EXISTS)
    	{ // 如果共享内存已经被其它程序打开,这时在_GetMemSizeFromSharedMem就能获取到一个正整数
    		TRACE("【提示】共享内存已被其它程序创建,尝试直接打开\n");
    		CloseHandle(m_hFileMap);
    		m_hFileMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, 1024, "Global\\SharedMemName");
    		if (NULL == m_hFileMap)
    		{
    			AfxMessageBox("打开共享内存失败 OpenFileMapping!");
    			return -3;
    		}
    		TRACE("【已存在】成功打开共享内存\n");
    	}
    	lpMemBuff = (BYTE*)MapViewOfFile(m_hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
    	if (lpMemBuff == NULL)
    	{
    		AfxMessageBox("内存映射到本地失败!");
    		return -6;
    	}
    
    展开全文
  • ShareMemLib将共享内存代码封装成lib,定义了发送者和监听者 两个进程在实例化ShareMemory时指定相同的map,并指定当前为发送者或监听者 发送者负责发送消息,监听者负责接受消息(监听者务必实现接受消息处理方法) ...
  • VC共享内存实现进程间数据的交换

    千次阅读 2017-08-31 09:05:10
    共享内存的使用  在Windows操作系统下,任何一个进程不允许读取、写入或是修改另一个进程的数据(包括变量、对象和内存分配等),但是在某个进程内创建的文件映射对象的视图却能够为多个其他进程所映射,这些...

    共享内存的使用

      在Windows操作系统下,任何一个进程不允许读取、写入或是修改另一个进程的数据(包括变量、对象和内存分配等),但是在某个进程内创建的文件映射对象的视图却能够为多个其他进程所映射,这些进程共享的是物理存储器的同一个页面。因此,当一个进程将数据写入此共享文件映射对象的视图时,其他进程可以立即获取数据变更情况。为了进一步提高数据交换的速度,还可以采用由系统页文件支持的内存映射文件而直接在内存区域使用,显然这种共享内存的方式是完全可以满足在进程间进行大数据量数据快速传输任务要求的。下面给出在两个相互独立的进程间通过文件映射对象来分配和访问同一个共享内存块的应用实例。在本例中,由发送方程序负责向接收方程序发送数据,文件映射对象由发送方创建和关闭,并且指定一个唯一的名字供接收程序使用。接收方程序直接通过这个唯一指定的名字打开此文件映射对象,并完成对数据的接收。

      在发送方程序中,首先通过CreateFileMapping()函数创建一个内存映射文件对象,如果创建成功则通过MapViewOfFile()函数将此文件映射对象的视图映射进地址空间,同时得到此映射视图的首址。可见,共享内存的创建主要是通过这两个函数完成的。这两个函数原形声明如下:

    HANDLE CreateFileMapping(HANDLE hFile,
    LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
    DWORD flProtect,
    DWORD dwMaximumSizeHigh,
    DWORD dwMaximumSizeLow,
    LPCTSTR lpName);
    LPVOID MapViewOfFile(HANDLE hFileMappingObject,
    DWORD dwDesiredAccess,
    DWORD dwFileOffsetHigh,
    DWORD dwFileOffsetLow,
    DWORD dwNumberOfBytesToMap);

      CreateFileMapping()函数参数hFile指定了待映射到进程地址空间的文件句柄,如果为无效句柄则系统会创建一个使用来自页文件而非指定磁盘文件存储器的文件映射对象。很显然,在本例中为了数据能快速交换,需要人为将此参数设定为INVALID_HANDLE_VALUE;参数flProtect设定了系统对页面采取的保护属性,由于需要进行读写操作,因此可以设置保护属性PAGE_READWRITE;双字型参数dwMaximumSizeHigh和dwMaximumSizeLow指定了所开辟共享内存区的最大字节数;最后的参数lpName用来给此共享内存设定一个名字,接收程序可以通过这个名字将其打开。MapViewOfFile()函数的参数hFileMappingObject为CreateFileMapping()返回的内存文件映像对象句柄;参数dwDesiredAccess再次指定对其数据的访问方式,而且需要同CreateFileMapping()函数所设置的保护属性相匹配。这里对保护属性的重复设置可以确保应用程序能更多的对数据的保护属性进行有效控制。下面给出创建共享内存的部分关键代

    hRecvMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 1000000, "DataMap");
    if (hRecvMap != NULL)
    {
    lpData = (LPBYTE)MapViewOfFile(hRecvMap, FILE_MAP_WRITE, 0, 0, 0);
    if (lpData == NULL)
    {
    CloseHandle(hRecvMap);
    hRecvMap = NULL;
    }
    }
    // 通知接收程序内存文件映射对象的视图已经打开
    HWND hRecv = ::FindWindow(NULL, DECODE_PROGRAMM);
    if (hRecv != NULL)
    ::PostMessage(hRecv, WM_MAP_OPEN, 0, 0);

      数据的传送实际是将数据从发送方写到共享内存中,然后由接收程序及时从中取走即可。数据从发送方程序写到共享内存比较简单,只需用memcpy()函数将数据拷贝过去,关键在于能及时通知接收程序数据已写入到共享内存,并让其即使取走。在这里仍采取消息通知的方式,当数据写入共享内存后通过PostMessage()函数向接收方程序发送消息,接收方在消息响应函数中完成对数据的读取:

    // 数据复制到共享内存
    memcpy(lpData, RecvBuf, sizeof(RecvBuf));
    // 通知接收方接收数据
    HWND hDeCode = ::FindWindow(NULL, DECODE_PROGRAMM);
    if (hDeCode != NULL)
    ::PostMessage(hDeCode, WM_DATA_READY, (WPARAM)0, (LPARAM)sizeof(RecvBuf));

      当数据传输结束,即将退出程序时,需要将映射进来的内存文件映射对象视图卸载和资源的释放等处理。这部分工作主要由UnmapViewOfFile()和CloseHandle()等函数完成:

    HWND hDeCode = ::FindWindow(NULL, DECODE_PROGRAMM);
    if (hDeCode != NULL)
    ::PostMessage(hDeCode, WM_MAP_CLOSE, 0, 0);
    if (lpData != NULL)
    {
    UnmapViewOfFile(lpData);
    lpData = NULL;
    }
    if (hRecvMap != NULL)
    {
    CloseHandle(hRecvMap);
    hRecvMap = NULL;
    }

      在接收程序中,在收到由发送放发出的WM_MAP_OPEN消息后,由OpenFileMapping()函数打开由名字"DataMap"指定的文件映射对象,如果执行成功,继续用MapViewOfFile()函数将此文件映射对象的视图映射到接收应用程序的地址空间并得到其首址:

    m_hReceiveMap = OpenFileMapping(FILE_MAP_READ, FALSE, "DataMap");
    if (m_hReceiveMap == NULL)
    return;
    m_lpbReceiveBuf = (LPBYTE)MapViewOfFile(m_hReceiveMap,FILE_MAP_READ,0,0,0);
    if (m_lpbReceiveBuf == NULL)
    {
    CloseHandle(m_hReceiveMap);
    m_hReceiveMap=NULL;
    }

      当发送方程序将数据写入到共享内存后,接收方将收到消息WM_DATA_READY,在响应函数中将数据从共享内存复制到本地缓存中,再进行后续的处理。同发送程序类似,在接收程序数据接收完毕后,也需要用UnmapViewOfFile()、CloseHandle()等函数完成对文件视图等打开过资源的释放:

    // 从共享内存接收数据
    memcpy(RecvBuf, (char*)(m_lpbReceiveBuf), (int)lParam);
    ……
    // 程序退出前资源的释放
    UnmapViewOfFile(m_lpbReceiveBuf);
    m_lpbReceiveBuf = NULL;
    CloseHandle(m_hReceiveMap);
    m_hReceiveMap = NULL;

      小结

      经实际测试,使用共享内存在处理大数据量数据的快速交换时表现出了良好的性能,在数据可靠性等方面要远远高于发送WM_COPYDATA消息的方式。这种大容量、高速的数据共享处理方式在设计高速数传通讯类软件中有着很好的使用效果。本文所述代码在Windows 2000下由Microsoft Visual C++ 6.0编译通过。

    //附:在dll中共享数据,在宿主进程中读取共享的数据;以下程序在WinXP Pro + VC6 通过测试

    //dll创建共享数据;

    // create mapping file

    HANDLE hSockSrvRecMap;
    LPBYTE lpData;
    char DataBuf[128];


    hSockSrvRecMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 1024, "SockSrvDataMap");
    if (hSockSrvRecMap != NULL)
    {
       lpData = (LPBYTE)MapViewOfFile(hSockSrvRecMap, FILE_MAP_WRITE, 0, 0, 0);
       if (lpData == NULL)
       {
        CloseHandle(hSockSrvRecMap);
        hSockSrvRecMap = NULL;
       }
    }
    for (int i=0; i<128; i++) {
       DataBuf[i] = i;
    }
    memcpy(lpData,DataBuf,sizeof(DataBuf));

    //宿主进程读取共享数据;

    m_hReceiveMap = OpenFileMapping(FILE_MAP_READ, FALSE, "SockSrvDataMap");
    if (m_hReceiveMap == NULL)
       return;
    m_lpbReceiveBuf = (LPBYTE)MapViewOfFile(m_hReceiveMap,FILE_MAP_READ,0,0,0);
    if (m_lpbReceiveBuf == NULL)
    {
       CloseHandle(m_hReceiveMap);
       m_hReceiveMap=NULL;
    }
    for (int i=0; i<18; i++) {
       TRACE("%d ",*(m_lpbReceiveBuf++));
    }
    TRACE("\n mapping data dump complete.\n");

    // 不需要内存映射的时候要关闭,两边都需要关闭内存映射文件

    if (m_lpbReceiveBuf != NULL)
    {
       UnmapViewOfFile(m_lpbReceiveBuf);
       m_lpbReceiveBuf = NULL;
    }
    if (m_hReceiveMap != NULL)
    {
       CloseHandle(m_hReceiveMap);
       m_hReceiveMap = NULL;
    }



    展开全文
  • VC++ 共享内存读写操作

    热门讨论 2014-01-02 13:58:34
    此解决方案含两个工程文件,一个是写操作工程文件,即把任意字符串写入创建的共享内存里,另外一个读操作工程文件,则是读取共享内存里的数据,从而实现了进程之间的共享内存读写操作。
  • VC端 void CSharedMemoryDlg::OnBnClickedOk() { ...先创建一个文件 CreateFile,即共享内存的实体 HANDLE hFile = CreateFile(TEXT("E:\zj.dat"), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_

    VC端

    void CSharedMemoryDlg::OnBnClickedOk()
    {
    	// TODO: 在此添加控件通知处理程序代码
    	//CDialogEx::OnOK();
    	m_text = "欢迎使用!";
    	UpdateData(false);
    	//1.先创建一个文件 CreateFile,即共享内存的实体
    	HANDLE hFile = CreateFile(TEXT("E:\zj.dat"), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    	if (hFile == NULL) {
    		printf("create file error!");
    		m_text = "create file error!";
    		UpdateData(false);
    		return;
    	}
    	// HANDLE hFile = (HANDLE)0xffffffff; //创建一个进程间共享的对象
    	//2.创建内存映射文件,上述硬盘中的文件hFile映射成为一个虚拟的映射文件 hMap ,即将物理文件与虚拟文件绑定,或者理解成将硬盘中的文件映射到内存当中。
    	HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 1024 * 1024, TEXT("ZJ"));
    	int rst = GetLastError();
    	if (hMap != NULL && rst == ERROR_ALREADY_EXISTS) {
    		printf("hMap error\n");
    		m_text = "hMap error\n";
    		CloseHandle(hMap);
    		hMap = NULL;
    		UpdateData(false);
    		return;
    	}
    	//3.加载并获得内存映射文件 MapViewOfFile 在内存中的地址
    	CHAR* pszText = NULL;
    	pszText = (CHAR*)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 1024 * 1024);
    	if (pszText == NULL) {
    		printf("view map error!");
    		m_text = "view map error!";
    		UpdateData(false);
    		return;
    	}
    	
    	//4.使用内存,即使用文件
    	sprintf(pszText, "hello my first mapping file!\n"); //其实是向文件中(共享内存中)写入了
    	printf(pszText);   //读
    	
    	
    	//while (1) {
    		//printf(pszText);   //读
    		//m_text = pszText;
    		//UpdateData(false);
    		//Sleep(3000);
    	//}
    	getchar();
    	//卸载映射,关闭文件
    	//UnmapViewOfFile((LPCVOID)pszText);
    	//CloseHandle(hMap);
    	//CloseHandle(hFile);
    	
    }
    
    
    void CSharedMemoryDlg::OnBnClickedCancel()
    {
    	
    	//1.打开内存映射文件(虚拟文件)
    	HANDLE hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, TRUE, TEXT("ZJ"));
    	if(hMap == NULL) {
    		printf("open file map error!");
    		return;
    	}
    	//2.获得地址,映射成内存 MapViewOfFile和服务器中的一样
    	CHAR* pszText = NULL;
    	pszText = (CHAR*)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 1024 * 1024);    
    	if (pszText == NULL) {
    		printf("map view error!\n");
    		return;
    	}
    	//3.使用内存
    	printf(pszText); //从文件中读(共享内存)  
    	m_text = pszText;
    	sprintf(pszText, "second data!\n"); //写入    
    	getchar();
    	//4.关闭映射,关闭文件。同服务器
    	UnmapViewOfFile(pszText);
    	CloseHandle(hMap);
    	hMap = NULL;
    	UpdateData(false);
    	return;
    }
    
    

    QT端

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QBuffer>
    #include <QDataStream>
    #include <QMessageBox>
    #include <QDebug>
    #include <QTextEdit>
    
    #include "windows.h"
    #include "stdio.h"
    #pragma warning(disable:4996)
    
    MainWindow::MainWindow(QWidget *parent)
        : QWidget(parent)
        , ui(new Ui::MainWindow)
    {
        m_btn = new QToolButton(this);
        m_btn->setText("btn");
    
        m_lbl = new QLabel(this);
        m_lbl->setText("Label");
        m_mainLayout = new QGridLayout(this);
    
        m_textEdit = new QTextEdit(this);
        m_textEdit->setText("ZJ");
    
        m_mainLayout->addWidget(m_textEdit);
        m_mainLayout->addWidget(m_lbl);
        m_mainLayout->addWidget(m_btn);
        this->setLayout(m_mainLayout);
        connect(m_btn, &QToolButton::clicked, this, &MainWindow::on_pushButton_clicked);
    
    
    
        this->setFixedSize(500, 500);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::sharing()
    {
        QString strText = "This is a SharedText";
        QBuffer buffer;
        buffer.open(QBuffer::ReadWrite);
        QDataStream stream(&buffer);
        stream << strText;
        int iSize = buffer.size();
        if(sharemem.isAttached())
        {
            sharemem.detach();
        }
        if(sharemem.create(iSize))
        {
            sharemem.lock();
            char* to = (char*) sharemem.data();
            const char* from = buffer.data();
            memcpy(to, from, qMin(sharemem.size(), iSize));
            sharemem.unlock();
        }
    }
    
    void MainWindow::on_pushButton_clicked()
    {
        if(0)
        {
            //方法3,QT与VC间进程通信, 此方法测试不成功
            //sharedMem.setKey("ZJ");
            sharedMem.setKey(m_textEdit->toPlainText());
            //sharedMem.setNativeKey(m_textEdit->toPlainText());
            //m_textEdit->setText(m_textEdit->toPlainText());
            //sharedMem.lock();
            if(!sharedMem.isAttached())
            {
                sharedMem.attach();
            }
            if (!sharedMem.attach(QSharedMemory::ReadOnly))
            {
                qDebug() << "atttach fail";
    
            }
            int iSize = sharedMem.size();
            QByteArray byteArr;
            byteArr.resize(iSize);
            char *to = byteArr.data();
            char *from = (char*) sharedMem.data();
            memcpy(to, from, iSize);
            QDataStream stream(&byteArr, QIODevice::ReadOnly);
            QString strText;
            stream >> strText;
            sharedMem.unlock();
            sharedMem.detach();
            m_lbl->setText(strText);
        }
    
        if(0)
        {
            //方法2,QT内部通信没问题
            sharemem.setKey("sharing");
            sharing();
            sharedMem.setKey("sharing");
            //sharedMem.setKey("ZJ");
            //QTextEdit *textEdit = new QTextEdit(this);
            //sharedMem.setNativeKey(QString("ZJ"));
            sharedMem.lock();
            if(!sharedMem.isAttached())
            {
                sharedMem.attach();
            }
            if (!sharedMem.attach(QSharedMemory::ReadOnly))
            {
                qDebug() << "atttach fail";
    
            }
            int iSize = sharedMem.size();
            QByteArray byteArr;
            byteArr.resize(iSize);
            char *to = byteArr.data();
            char *from = (char*) sharedMem.data();
            memcpy(to, from, iSize);
            QDataStream stream(&byteArr, QIODevice::ReadOnly);
            QString strText;
            stream >> strText;
            sharedMem.unlock();
            sharedMem.detach();
            m_lbl->setText(strText);
    
        }
    
        if(0)
        {
            //方法1.使用API操作没问题,QT与VC间通信
            //1.打开内存映射文件(虚拟文件)
            HANDLE hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, TRUE, TEXT("ZJ"));
            if(hMap == nullptr) {
                printf("open file map error!");
                m_lbl->setText(QString("open file map error!"));
                return;
            }
            //2.获得地址,映射成内存 MapViewOfFile和服务器中的一样
            CHAR* pszText = nullptr;
            pszText = (CHAR*)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 1024 * 1024);
            if (pszText == nullptr) {
                printf("map view error!\n");
                m_lbl->setText(QString("map view error!\n"));
                return;
            }
            //3.使用内存
            printf(pszText); //从文件中读(共享内存)
            m_lbl->setText(QString(pszText));
            sprintf(pszText, "QT data!\n"); //写入
            //4.关闭映射,关闭文件。同服务器
            UnmapViewOfFile(pszText);
            CloseHandle(hMap);
            hMap = nullptr;
        }
    
    }
    
    

    在这里插入图片描述
    VC源程序地址
    QT源程序地址

    展开全文
  • 共享内存,进程通信,进程同步 源代码 vs2005
  • 通过图文描述介绍MFC与dll之间通过共享内存建立通信,文件内附有可直接复制的代码,文档和文档里的代码是基于VS2017编写的。前两天通过VS2019实现,文件里的代码在通过VS2019仍然可以实现。初学MFC与dll之间通信的...
  • 在VC++ 6.0下利用共享内存、消息实现内部进程通讯C++源代码程序小实例
  • 通过vc使用共享内存多大文件进行分析,并且输出html文件,代码可以重构
  •  在Windows操作系统下,任何一个进程不允许读取、写入或是修改另一个进程的数据(包括变量、对象和内存分配等),但是在某个进程内创建的文件映射对象的视图却能够为多个其他进程所映射,这些进程共享的是物理...
    作者:中国电波传播研究所青岛分所:郎锐 
    

        在Windows操作系统下,任何一个进程不允许读取、写入或是修改另一个进程的数据(包括变量、对象和内存分配等),但是在某个进程内创建的文件映射对象的视图却能够为多个其他进程所映射,这些进程共享的是物理存储器的同一个页面。因此,当一个进程将数据写入此共享文件映射对象的视图时,其他进程可以立即获取数据变更情况。为了进一步提高数据交换的速度,还可以采用由系统页文件支持的内存映射文件而直接在内存区域使用,显然这种共享内存的方式是完全可以满足在进程间进行大数据量数据快速传输任务要求的。

        下面给出在两个相互独立的进程间通过文件映射对象来分配和访问同一个共享内存块的应用实例。在本例中,由发送方程序负责向接收方程序发送数据,文件映射对象由发送方创建和关闭,并且指定一个唯一的名字供接收程序使用。接收方程序直接通过这个唯一指定的名字打开此文件映射对象,并完成对数据的接收。

      在发送方程序中,首先通过CreateFileMapping()函数创建一个内存映射文件对象,如果创建成功则通过MapViewOfFile()函数将此文件映射对象的视图映射进地址空间,同时得到此映射视图的首址。可见,共享内存的创建主要是通过这两个函数完成的。这两个函数原形声明如下:

    HANDLE CreateFileMapping(HANDLE hFile,
    LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
    DWORD flProtect,
    DWORD dwMaximumSizeHigh,
    DWORD dwMaximumSizeLow,
    LPCTSTR lpName);


    LPVOID MapViewOfFile(HANDLE hFileMappingObject,
    DWORD dwDesiredAccess,
    DWORD dwFileOffsetHigh,
    DWORD dwFileOffsetLow,
    DWORD dwNumberOfBytesToMap);

        CreateFileMapping()函数参数hFile指定了待映射到进程地址空间的文件句柄,如果为无效句柄则系统会创建一个使用来自页文件而非指定磁盘文件存储器的文件映射对象。很显然,在本例中为了数据能快速交换,需要人为将此参数设定为INVALID_HANDLE_VALUE;参数flProtect设定了系统对页面采取的保护属性,由于需要进行读写操作,因此可以设置保护属性PAGE_READWRITE;双字型参数dwMaximumSizeHigh和dwMaximumSizeLow指定了所开辟共享内存区的最大字节数;最后的参数lpName用来给此共享内存设定一个名字,接收程序可以通过这个名字将其打开。

        MapViewOfFile()函数的参数hFileMappingObject为CreateFileMapping()返回的内存文件映像对象句柄;参数dwDesiredAccess再次指定对其数据的访问方式,而且需要同CreateFileMapping()函数所设置的保护属性相匹配。这里对保护属性的重复设置可以确保应用程序能更多的对数据的保护属性进行有效控制。

       下面给出创建共享内存的部分关键代码:

    hRecvMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 1000000, "DataMap");
    if (hRecvMap != NULL)
    {
       lpData = (LPBYTE)MapViewOfFile(hRecvMap, FILE_MAP_WRITE, 0, 0, 0);
       if (lpData == NULL)
       {
          CloseHandle(hRecvMap);
          hRecvMap = NULL;
       }
    }
    // 通知接收程序内存文件映射对象的视图已经打开
    HWND hRecv = ::FindWindow(NULL, DECODE_PROGRAMM);
    if (hRecv != NULL)
    {

        ::PostMessage(hRecv, WM_MAP_OPEN, 0, 0);

    }

      数据的传送实际是将数据从发送方写到共享内存中,然后由接收程序及时从中取走即可。数据从发送方程序写到共享内存比较简单,只需用memcpy()函数将数据拷贝过去,关键在于能及时通知接收程序数据已写入到共享内存,并让其即使取走。在这里仍采取消息通知的方式,当数据写入共享内存后通过PostMessage()函数向接收方程序发送消息,接收方在消息响应函数中完成对数据的读取:

    // 数据复制到共享内存
    memcpy(lpData, RecvBuf, sizeof(RecvBuf));
    // 通知接收方接收数据
    HWND hDeCode = ::FindWindow(NULL, DECODE_PROGRAMM);
    if (hDeCode != NULL)
    {

        ::PostMessage(hDeCode, WM_DATA_READY, (WPARAM)0, (LPARAM)sizeof(RecvBuf));

    }

       当数据传输结束,即将退出程序时,需要将映射进来的内存文件映射对象视图卸载和资源的释放等处理。这部分工作主要由UnmapViewOfFile()和CloseHandle()等函数完成:

    HWND hDeCode = ::FindWindow(NULL, DECODE_PROGRAMM);
    if (hDeCode != NULL)
    {

        ::PostMessage(hDeCode, WM_MAP_CLOSE, 0, 0);

    }
    if (lpData != NULL)
    {
       UnmapViewOfFile(lpData);
       lpData = NULL;
    }
    if (hRecvMap != NULL)
    {
       CloseHandle(hRecvMap);
       hRecvMap = NULL;
    }

      在接收程序中,在收到由发送放发出的WM_MAP_OPEN消息后,由OpenFileMapping()函数打开由名字"DataMap"指定的文件映射对象,如果执行成功,继续用MapViewOfFile()函数将此文件映射对象的视图映射到接收应用程序的地址空间并得到其首址:

    m_hReceiveMap = OpenFileMapping(FILE_MAP_READ, FALSE, "DataMap");
    if (m_hReceiveMap == NULL)
    {

       return;

    }
    m_lpbReceiveBuf = (LPBYTE)MapViewOfFile(m_hReceiveMap,FILE_MAP_READ,0,0,0);
    if (m_lpbReceiveBuf == NULL)
    {
        CloseHandle(m_hReceiveMap);
        m_hReceiveMap=NULL;
    }

      当发送方程序将数据写入到共享内存后,接收方将收到消息WM_DATA_READY,在响应函数中将数据从共享内存复制到本地缓存中,再进行后续的处理。同发送程序类似,在接收程序数据接收完毕后,也需要用UnmapViewOfFile()、CloseHandle()等函数完成对文件视图等打开过资源的释放:

    // 从共享内存接收数据
    memcpy(RecvBuf, (char*)(m_lpbReceiveBuf), (int)lParam);
    ///do what you want here///

       当接收方收到消息WM_MAP_CLOSE,在响应函数释放资源

    // 程序退出前释放资源
    UnmapViewOfFile(m_lpbReceiveBuf);
    m_lpbReceiveBuf = NULL;
    CloseHandle(m_hReceiveMap);
    m_hReceiveMap = NULL;

      小结

      经实际测试,使用共享内存在处理大数据量数据的快速交换时表现出了良好的性能,在数据可靠性等方面要远远高于发送WM_COPYDATA消息的方式。这种大容量、高速的数据共享处理方式在设计高速数传通讯类软件中有着很好的使用效果。本文所述代码在Windows 2000下由Microsoft Visual C++ 6.0编译通过。

     

    原文地址:http://blog.sina.com.cn/s/blog_4b44e1c00100cf8l.html

    展开全文
  • Java局域网通信——飞鸽传书源代码 28个目标文件 内容索引:JAVA源码,媒体网络,飞鸽传书 Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java...
  • RTX 共享内存示例源代码

    热门讨论 2010-08-02 10:56:16
    RTX和UI程序直接,如何通过共享内存来沟通,这里简单给出一个示例代码
  • 下面用共享映射文件的方式实现进程间通信,代码可以运行。 一、浅理解 &amp;amp;amp;amp;amp;amp;amp;amp;nbsp;&amp;amp;amp;amp;amp;amp;amp;amp;nbsp;&amp;amp;amp;amp;amp;amp;amp;amp;nbsp;&...
  • 共享单车、共享充电宝、共享雨伞,世间的共享有千万种,而我独爱共享内存。早期的共享内存,着重于强调把同一片内存,map到多个进程的虚拟地址空间(在相应进程找到一个VMA区域),以便于CPU可以在各个进程访问到这...
  • 使用C#实现共享内存

    2010-08-26 22:00:24
    VS2005 C# 共享内存代码
  • Java与VC/C/C++共享内存

    千次阅读 2019-06-13 21:44:21
    1. 采用socket的方式:调用共享内存 你得用VC写个DLL,JAVA调用。 2. SOCKET是最好的选择。共享内存好像也是SOCKET实现的。 用VC写DLL然后调用。分布式最终也是用的SOCKET。缓存等等 10年我弄过 进程间通信...
  • 更新时间:2020-10-27 15:26:02 原文链接原理python没有办法直接和c++共享内存交互,需要间接调用c++打包好的库来实现流程C++共享内存打包成库python调用C++库往共享内存存图像数据C++测试代码共享内存读取图像数据...
  • VC++6.0共享内存技术总结 程序1 -- 建立共享区,写数据: Cpp代码 int main(int argc, char* argv[])  {   HANDLE lhShareMemory;   char* lpBuffer = NULL;     lhShareMemory =...
  • #include "windows.h" #include "stdio.h" #pragma warning(disable:4996) void CSharedMemoryDlg::...先创建一个文件 CreateFile,即共享内存的实体 HANDLE hFile = CreateFile(TEXT("E:\zj.dat"), GENERIC_READ | GE
  • 共享内存是进程间共享数据最简单的方式,python中有两个方法来创建共享的数据对象,分别是:Value(typecode_or_type,*args,lock=True)--开辟共享内存空间存储值类型Array(typecode_or_type,size_or_initializer,*,...
  • 内容索引:VC/C++源码,其它分类,日志,LLogTrace LLogTrace 通用日志调试工具VC代码,采用共享内存实现,作为调试程序用的LOG跟踪程序。包含了Delphi、VB、VC++三种语言的源代码版本。程序可以设置不同级别的LOG...
  • 这里it's我的代码:Linux-C从共享内存中读取已损坏的数据这是作家(我已经中省略无关的代码)int main() {char message[MAX_BUF];key_t key;int sharedMemoryId;int semaphoreId;char *vc1;char *data;pid_t p3;...
  • 我没有访问FirstLayer的源代码,但我需要从托管代码中调用它。问题是,FirstLayer大量使用std :: vector和std :: string作为函数参数,并且没有办法将这些类型直接封装到C#应用程序中。Second_Layer,我能想到的是...
  • 代码进行了共享内存的通信演示。 此演示非常简单,只是演示如何使用,没有考虑性能、方式等,如果需要拿到真正的代码中使用,则需要考虑其它额外的工作,比如方式、效率等。 使用vc6.0
  • 共享内存封装类

    2021-02-26 16:30:58
    http://blog.chinaunix.net/u1/59687/showart_496412.html本文介绍一个共享内存封装类,使共享内存的使用更简单化,特别适合更懒的程序员使用:-) 一、实现目标:简单化使用共享内存 二、使用说明:1. 创建共享内存...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 22,360
精华内容 8,944
关键字:

vc共享内存代码