Use of catlfilemapping shared memory on windows and internal mechanisms

Source: Internet
Author: User
Tags guid identifier

Preface:

Use CEF to load Web pages. When JS interacts with C + +. You need to send some messages to the main form to notify the interface to do the corresponding processing. However, because CEF uses the chrome kernel as a multi-process architecture. The rendering engine is not in the same process as the main program. So. It's a matter of course to think about using shared memory. To make it easier to use, we chose the shared memory operation class that is encapsulated within ATL: catlfilemapping.

catlfilemapping using:

Define the structure, including the data you need to share, here we just need to share the handle of the main form

Define process share data structure body struct process_share_data{hwndhmainwnd;};
Use </span>vs to create a GUID that uniquely identifies this shared memory </p><p>const TCHAR szshareguid[] = _t (" 4f836c8d-f55e-4d88-a0bf-9acdc0a33b31 "); Define shared memory global variables
extern catlfilemapping<process_share_data> G_sharedata;

Initialize this shared memory and assign values to the data

G_sharedata.mapsharedmem (sizeof (process_share_data), szshareguid);((P rocess_share_data*) g_sharedata) Hmainwnd=pmainwnd->gethwnd ();
All right. This allows the shared memory data to be initialized. The CEF process can also use this data directly after it has been created.

Open shared memory, remove required data
G_sharedata.openmapping (Szshareguid, sizeof (Process_share_data)); HWND hwnd = ((process_share_data*) g_sharedata)->hmainwnd;
Then, turn this shared memory handle off

G_sharedata.unmap ();
it's quite simple. We can easily share data across multiple processes without needing to know the internal API calls and implementations.

But. Ape as a program. We should know the reason why.

Then go inside and see what you can do with ATL code anyway.

Internal implementation:

The first is Mapsharedmem, creating a piece of shared memory,

HRESULT Mapsharedmem (</span>

_in_ size_t nmappingsize,_in_z_ lpctstr szname,_out_opt_ bool* pbalreadyexisted = Null,_in_opt_ LPSECURITY_ATTRIBUTES LPSA = null,_in_ DWORD dwmappingprotection = page_readwrite,_in_ DWORD dwviewdesiredaccess = file_map_all_access) throw () {Atlassume (M_pdata = = NULL); Atlassume (m_hmapping = = NULL); Atlassert (nmappingsize > 0); Atlassert (SzName! = NULL); If you just want a regular chunk of memory, use a heap allocatorm_nmappingsize = nmappingsize; Ularge_integer Nsize;nsize.quadpart = nmappingsize;m_hmapping =:: CreateFileMapping (Invalid_handle_value, LPSA, Dwmappingprotection, Nsize.highpart, Nsize.lowpart, szName); if (m_hmapping = = NULL) return atlhresultfromlasterror (); if (pbalreadyexisted! = NULL) *pbalreadyexisted = (GetLastError () = = error_already_exists); m_dwviewdesiredaccess = Dwviewdesiredaccess;m_noffset.quadpart = 0;m_pdata =:: Mapviewoffileex (M_hmapping, m_dwviewdesiredaccess, m_ Noffset.highpart, M_noffset.lowpart, m_nmappingsize, NULL); if (m_pdata = = NULL) {HRESULT hr;hr = atLhresultfromlasterror ();:: CloseHandle (m_hmapping); m_hmapping = Null;return hr;} return S_OK;}
A invalid_handle_value is created to create a memory map independent of the physical file by passing in a createfilemapping. The size of the incoming mapped memory.

It then calls Mapviewoffileex to map it into memory. Returns the memory header address M_pdata, which is a member variable of catlfilemappingbase.

Then we look at the definition of catlfilemapping

Template <typename T = Char>class catlfilemapping:public catlfilemappingbase{public:operator T* () const throw () {R Eturn reinterpret_cast<t*> (GetData ());};

derived from CAtlFileMappingBase, and then overloaded with *. Use reinterpret_cast to translate the memory-mapped address into the address of our data structure, so that we can access the data of our defined structure directly through the catlfilemapping pointer.

Other processes use shared memory, and then see the implementation of the Openmapping function

HRESULT openmapping (_in_z_ lpctstr szname,_in_ size_t nmappingsize,_in_ ulonglong noffset = 0,_in_ DWORD dwViewDesiredAcc ESS = file_map_all_access) throw () {atlassume (m_pdata = = NULL); Atlassume (m_hmapping = = NULL); Atlassert (SzName! = NULL); If you just want a regular chunk of memory, use a heap allocatorm_nmappingsize = Nmappingsize;m_dwviewdesiredaccess = d wviewdesiredaccess;m_hmapping =:: OpenFileMapping (M_dwviewdesiredaccess, FALSE, szName); if (m_hmapping = = NULL) return Atlhresultfromlasterror (); m_dwviewdesiredaccess = Dwviewdesiredaccess;m_noffset.quadpart = NOffset;m_pData =:: Mapviewoffileex (m_hmapping, m_dwviewdesiredaccess, M_noffset.highpart, M_noffset.lowpart, M_nMappingSize, NULL); M_pdata = = NULL) {HRESULT hr;hr = Atlhresultfromlasterror ();:: CloseHandle (m_hmapping); m_hmapping = Null;return hr;} return S_OK;}

Since our shared memory was created, a unique GUID identifier was used to find the kernel object of this shared memory through API OpenFileMapping, and then mapviewoffileex the same to map it into the current process's memory space. This allows us to access the data in the shared memory.

After use is complete. Kernel objects are freed. Then look at the implementation code of UNMAP

HRESULT Unmap () throw () {HRESULT hr = S_OK;IF (m_pdata! = NULL) {if (!::unmapviewoffile (m_pdata)) hr = Atlhresultfromlasterr or (); m_pdata = NULL;} if (m_hmapping! = NULL) {if (!::closehandle (m_hmapping) && succeeded (hr)) hr = Atlhresultfromlasterror (); m_ hmapping = NULL;} return HR;}
The memory map of the current process is first dismissed, and then the handle to the mapped kernel object is closed.


Summary:

Use CreateFileMapping to create a memory map with a unique identifier (GUID) that Mapviewoffileex map to the memory space of the current process. Save the data that needs to be shared into this memory.

When other processes access shared memory. OpenFileMapping obtains the kernel handle of this shared memory by a unique identifier (GUID), calls Mapviewoffileex maps to its own memory space, then reads the data inside, and uses UnmapViewOfFile to de-map when it is finished. CloseHandle closes the kernel object handle.

Although the use of catlfilemapping is simpler and more convenient. However, we still need to understand the mechanism of memory mapping.




Use of catlfilemapping shared memory on windows and internal mechanisms

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.