【问题标题】:Shared data Filemapping共享数据文件映射
【发布时间】:2018-04-03 09:47:43
【问题描述】:

您好,我想使用来自 microsoft 的文件映射将 P1 进程中的类中的对象共享到 P2.exe 进程:https://msdn.microsoft.com/fr-fr/library/windows/desktop/aa366537(v=vs.85).aspx

P1 写入数据,P2 读取它们。我想共享所有数据,但它不起作用。

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;
}

所以我只尝试使用 2 个字符串进行测试:add.nameLogFile= "Logfil" 和 add.nameWindow = "Windowstest";两者的大小。 P2 可以很好地读取这两个字符串。

但是当我有一个字符(add.nameWindow = "Windowstest+" size 均为 28)时,它不再起作用了。这可能是大小或内存错误:

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

所以我的问题是:

如何增加文件或缓冲区的数据大小? 如何在文件映射中传递我的对象类的所有成员(两个字符串和 HWND hwndWindow;HANDLE histFile;WIN32_FIND_DATA 数据文件) 是否有其他方法可以在两个进程之间共享来自一个对象的数据。

PS:我阅读了很多论坛,但没有找到答案或不明白。

谢谢大家。

【问题讨论】:

    标签: c++ windows process msdn file-mapping


    【解决方案1】:

    这真的行不通。

    std::string 存储一个短字符串时,这些字符可能存储在std::string 对象中。但是,当字符串变大时,将在堆上分配额外的空间 - 在 string 对象之外。

    这个堆空间没有写入文件,然后它就不再工作了。

    很遗憾,您必须从一开始就重新考虑这一点。

    【讨论】:

    • 但是我没有在运行时修改字符串。我在开头声明了字符串并且从未更改过它。但是,如果他的字符串大小为 27,它可以工作,但如果他的大小为 28,它将无法工作。我不明白为什么即使在开始时我也无法更改尺寸。
    • 这是因为 basic_string 的 VC 实现对小字符串使用包含的缓冲区,而对于较大的字符串则进入堆。你达到了门槛。想想字符串对象。它们在记忆中是什么样子的?在内部(当足够大时)它们包含一个 POINTER。它指向进程 A 堆中的一块内存。因此,当您在进程 A 中分配一个足够大的字符串并对其进行内存映射时,它共享该指针,但不共享堆块。怎么可能?进程 B 认为指针指向它的 OWN 堆,但它没有。访问它当然是无效的
    • 好的,我可以使用其他格式吗,比如写在同一个地址的 char*?我的程序可以与其他成员 HANDLE、HWNDLE 一起使用,还是指向其他堆块的指针是一样的?
    猜你喜欢
    • 2011-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-08
    • 2017-03-01
    • 1970-01-01
    • 2012-09-06
    • 2011-10-20
    相关资源
    最近更新 更多