c++ - Acessing a file mapping with a other function -
c++ - Acessing a file mapping with a other function -
hello have process1 correctly creates , mapped file(mmap windows). can correcty acces mmap en write info in it, other process can read data.
there problem when want access mapped file other function of process1.
i create mapped file this:
tchar szname[]=text("global\\myfilemappingobject"); int mancontrol(void* pvbrick, handle hmutex); int main() { //handels , vars ipc handle hmapfile; lpctstr pbuf; char szmsg[256]; string datastr = ""; //create file mapping hmapfile = createfilemapping(invalid_handle_value, null, page_readwrite, 0, buf_size, szname); if (hmapfile == null) { printf("failed create mmap \n"); homecoming 1; } //map file(mapviewoffile) , homecoming pointer of mapped file(file view) pbuf = (lptstr) mapviewoffile(hmapfile, file_map_all_access, 0, 0, buf_size); if (pbuf == null) { printf("failed map mmap"); closehandle(hmapfile); homecoming 1; }
in function want acces mapped file , write info looks this:
int mancontrol(void* pvbrick, handle hmutex, lpcstr pbuf) { char msg[256]; string datastring = ""; datastring = "aaaa en bbbb"; strcpy(msg, datastring.c_str()); copymemory((pvoid)pbuf, msg, strlen(msg)); datastring = "";
i don't new error proces2 can't reads no data(in main info send there process2 can read). need open mapped file in function , map again? or there wrong argument passing?
i bert-jan's guess correct.
you can mapping real disk file, passing real file handle createfile() first parameter createfilemapping(), mapped file persists , info remain accessible.
you, on other hand, have passed invalid_handle_value first parameter, creates temporary memory file. there no mappings file, erased. when sec process creates mapping, gets brand new file.
in real life, 2 processes run longer periods, may not problem.
just fun, knocked quick sample program. if programme called fmap.exe (as test version is) run 1 instance "fmap server" , sec "fmap" (which client.
type text client , printed server.
// fmap.cpp #include <windows.h> #include <iostream> #include <string> #include <algorithm> #include <stdexcept> // convenience class manage mutex class cmutex { public: cmutex(const char *szname) { std::string sname = std::string("mutex_") + szname; m_hmutex = ::createmutex( null, // __in_opt lpsecurity_attributes lpmutexattributes, false, // __in bool binitialowner, sname.c_str()); // __in_opt lpctstr lpname if (!m_hmutex) throw std::runtime_error("failed create mutex"); } ~cmutex() { if (m_hmutex) ::closehandle(m_hmutex); } void lock() { ::waitforsingleobject(m_hmutex, infinite); } void unlock() { ::releasemutex(m_hmutex); } private: handle m_hmutex; }; // convenience class lock mutex , unlock when // goes out of scope. class cautolock { public: cautolock(cmutex &m) : m_mutex(m) { m_mutex.lock(); } ~cautolock() { m_mutex.unlock(); } private: cmutex &m_mutex; }; // class manage mapped file // uses same name file , mutex class cmappedfile { public: cmappedfile(const char *szname) : m_hmapfile(null) , m_szbuff(null) , m_mutex(szname) { m_hmapfile = createfilemapping( invalid_handle_value, // handle hfile, null, // lpsecurity_attributes lpfilemappingattributes, page_readwrite, // dword flprotect, 0, // dword dwmaximumsizehigh, nbuffsize, // dword dwmaximumsizelow, szname); // lpctstr lpname if (!m_hmapfile) throw std::runtime_error("failed create mapping"); m_szbase = reinterpret_cast<char *>( mapviewoffile( m_hmapfile, // handle hfilemappingobject, file_map_all_access, // dword dwdesiredaccess, 0, // dword dwfileoffsethigh, 0, // dword dwfileoffsetlow, nbuffsize)); // dword dwnumberofbytestomap if (!m_szbase) throw std::runtime_error("failed create view"); // reserve first few bytes of file length variable. // rest buffer. m_szbuff = m_szbase + sizeof(size_t); } ~cmappedfile() { if (m_szbase) { unmapviewoffile(m_szbase); } if (m_hmapfile) { closehandle(m_hmapfile); } } // add together string mapped file void put(const std::string &sval) { // lock mutex cautolock l(m_mutex); // create reference origin of buffer size_t &nlength = *reinterpret_cast<size_t *>(m_szbase); // check overflow if (nlength + sval.length() >= nbuffsize) throw std::runtime_error("buffer overflow"); // re-create string buffer , increment length std::copy(sval.begin(), sval.end(), m_szbuff + nlength); nlength += sval.length(); } // read string mapped file , // clear length field, indicating // info has been read. std::string get() { // lock mutex cautolock l(m_mutex); // create reference origin of buffer size_t &nlength = *reinterpret_cast<size_t *>(m_szbase); std::string sval; if (nlength) { // if in buffer read ot sval.assign(m_szbuff, nlength); // reset length we've read buffer nlength = 0; } homecoming sval; } private: handle m_hmapfile; char * m_szbase; char * m_szbuff; cmutex m_mutex; enum { nbasesize=1024, // whole file size nbuffsize=nbasesize-sizeof(size_t) // buffer size, after size has been reserved }; }; void doclient(cmappedfile &m); void doserver(cmappedfile &m); int main(int argc, char* argv[]) { seek { const char szuniquename[] = "ca249329_acae_11e0_9594_6cf0494804c2"; cmappedfile m(szuniquename); std::string sserver("server"); if (argc==2 && sserver==argv[1]) doserver(m); else doclient(m); } grab (std::exception &e) { std::cerr << e.what() << std::endl; } homecoming 0; } void doclient(cmappedfile &m) { std::cout << "client running\n\n"; std::string s; while (std::getline(std::cin, s)) m.put(s); } void doserver(cmappedfile &m) { std::cout << "server running\n\n"; while (1) { std::string s = m.get(); if (s.length()) std::cout << s << std::endl; } }
c++ memory-mapped-files
Comments
Post a Comment