0

Hello I want to share an object from a class from a P1 process to a P2.exe process using the filemapping from microsoft: https://msdn.microsoft.com/fr-fr/library/windows/desktop/aa366537(v=vs.85).aspx.

P1 write the datas and P2 read them. I want to share all the datas but it doesn't work.

P1:

#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <iostream>
#include <string>
using namespace std;
TCHAR szName[] = TEXT("Global\\MyFileMappingObject");
class Object
{
public:
    string nameWindow;
    string nameLogFile;
    HWND hwndWindow;
    HANDLE histFile;
    WIN32_FIND_DATA dataFile;
};// members to read
int _tmain()
{
    Object add;

    HANDLE hMapFile;
    add.nameLogFile= "Logfil";
    add.nameWindow = "Windowstest";
    Table *bufData;
    hMapFile = CreateFileMapping(
        INVALID_HANDLE_VALUE,    // use paging file
        NULL,                    // default security
        PAGE_READWRITE,          // read/write access
        0,                       // maximum object size (high-order DWORD)
        sizeof(Table),                // maximum object size (low-order DWORD)
        szName);                 // name of mapping object

    if (hMapFile == NULL)
    {
        _tprintf(TEXT("Could not create file mapping object (%d).\n"),
            GetLastError());
        return false;
    }
    bufData = (Object*)MapViewOfFile(hMapFile,   // handle to map object
        FILE_MAP_ALL_ACCESS, // read/write permission
        0,
        0,
        sizeof(Table));
    if (bufData == NULL)
    {
        _tprintf(TEXT("Could not map view of file (%d).\n"),
            GetLastError());

        CloseHandle(hMapFile);

        return false;
    }
    CopyMemory((PVOID)bufData, &add, sizeof(Table));
        cout << "Mise en memoire " << endl;

    _getch();

    UnmapViewOfFile(bufData);

    CloseHandle(hMapFile);

}

P2:

#include <windows.h>
#include <iostream>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <string>
using namespace std;
#pragma comment(lib, "user32.lib")
class Object
{
public:
    string nameWindow;
    string nameLogFile;
    HWND hwndWindow;
    HANDLE histFile;
    WIN32_FIND_DATA dataFile;
};// members to write
TCHAR szName[] = TEXT("Global\\MyFileMappingObject");

int _tmain()
{
    HANDLE hMapFile;
    LPCTSTR pBuf;
    Table *bufData=new Table;
    hMapFile = OpenFileMapping(
        FILE_MAP_ALL_ACCESS,   // read/write access
        FALSE,                 // do not inherit the name
        szName);               // name of mapping object

    if (hMapFile == NULL)
    {
        _tprintf(TEXT("Could not open file mapping object (%d).\n"),
            GetLastError());
        return 1;
    }

    bufData = (Object*)MapViewOfFile(hMapFile, // handle to map object
        FILE_MAP_ALL_ACCESS,  // read/write permission
        0,
        0,
        sizeof(Object));

    if (bufData == NULL)
    {
        _tprintf(TEXT("Could not map view of file (%d).\n"),
            GetLastError());

        CloseHandle(hMapFile);

        return 1;
    }
    cout << "DATA" << endl;
    cout << "Log:" << bufData->nameLogFile<<endl;
    cout << "Window:" << bufData->nameWindow << endl;


    UnmapViewOfFile(bufData);

    CloseHandle(hMapFile);
    system("pause");
    return 0;
}

So I try with only 2 strings for the tests:add.nameLogFile= "Logfil" and add.nameWindow = "Windowstest"; size of both. It works the P2 reads well the two strings.

But when I had one character (add.nameWindow = "Windowstest+" size of 28 both) it doesnt'work anymore. It may be a size or memory error with this:

TCHAR szName[] = TEXT("Global\MyFileMappingObject");

So my questions are:

How increase the data size of the file or buffer? How can I pass all members of my object class in the filemapping (the two strings and HWND hwndWindow; HANDLE histFile; WIN32_FIND_DATA dataFile) Is there an other method two share datas from an object between two process.

PS: I read many forum and I don't find my answer or no understand.

Thanks for all.

John Summer
  • 15
  • 1
  • 5

1 Answers1

1

This doesn't really work.

When a std::string stores a short string, the characters might be stored inside the std::string object. However, when the string grows larger, additional space will be allocated on the heap - outside of the string object.

This heap space is not written to the file and then it doesn't work anymore.

Unfortunately you will have to rethink this from the beginning.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
  • But I didn't modify the string while running. I declared the string at the beginning and never changed it. But if he has a string size of 27 it works but with a size of 28 it won't work. I don't understand why I can't change the size even at the beginnig. – John Summer Oct 22 '17 at 21:54
  • This is because the VC implementation of basic_string uses a contained buffer for small strings but goes to the heap for larger ones. You hit the threshold. Think of the string objects. What do they look like in memory? Inside (when large enough) they contain a POINTER. It points to a block of memory from the heap of Process A. So when you allocate a large-enough string in process A and memory map it, it shares that pointer but it doesnt share the heap block. How could it? Process B thinks that pointer points to its OWN heap which it does NOT. Accessing it is, of course, not valid – Joe Oct 22 '17 at 22:15
  • Ok so is there an other format I can use like char* which is written in the same address? And my program can work with the other member HANDLE, HWNDLE or is it the same thing a pointer to an other heap block? – John Summer Oct 22 '17 at 22:38