c++ WINAPI 共享内存结构数组

标签 c++ arrays windows shared-memory

我正在尝试使用 WINAPI 通过共享命名内存来共享结构数组。我能够创建和管理共享内存,但是当尝试共享结构数组时,读取时数组的大小始终为 0。

下面是我编写的测试代码,它应该写入/读取 10 个条目的数组,但即使这样也是失败的。然而,我的目标是编写/读取包含 2 个动态数组的动态结构数组以及它们目前已包含的信息。

我知道我不应该在进程之间共享指针,因为它们可能指向随机值。因此,我正在使用 new 为数组分配内存。

这是我目前所拥有的:

在两个进程中共享:

#define MEMSIZE 90024 

typedef struct {
    int id;
    int type;
    int count;
} Entry;

过程 1:

extern HANDLE hMapObject;
extern void* vMapData;

std::vector<Entry> entries;//collection of entries

BOOL DumpEntries(TCHAR* memName) {//Returns true, writing 10 entries
    int size = min(10, entries.size());

    Entry* eArray = new Entry[size];
    for (int i = 0; i < size; i++) {
        eArray[i] = entries.at(i);
    }

    ::hMapObject = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, MEMSIZE, memName);
    if (::hMapObject == NULL) {
        return FALSE;
    }

    ::vMapData = MapViewOfFile(::hMapObject, FILE_MAP_ALL_ACCESS, 0, 0, MEMSIZE);
    if (::vMapData == NULL) {
        CloseHandle(::hMapObject);
        return FALSE;
    }

    CopyMemory(::vMapData, eArray, (size * sizeof(Entry)));
    UnmapViewOfFile(::vMapData);
    //delete[] eArray;
    return TRUE;
}

过程 2:

BOOL ReadEntries(TCHAR* memName, Entry* entries) {//Returns true reading 0 entries
    HANDLE hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, memName);
    if (hMapFile == NULL) {
        return FALSE;
    }

    Entry* tmpEntries = (Entry*)(MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 10 * sizeof(Entry)));
    if (tmpEntries == NULL) {
        CloseHandle(hMapFile);
        return FALSE;
    }

    entries = new Entry[10];

    for (int i = 0; i < 10; i++) {
        entries[i] = tmpEntries[i];
    }

    UnmapViewOfFile(tmpEntries);
    CloseHandle(hMapFile);
    return TRUE;
}

写入 10 个条目似乎有效,但是当尝试读取内存时,它成功返回并且大小 数组的值为 0,如下所示:

Entry* entries = NULL;
if (ReadEntries(TEXT("Global\Entries"), entries)) {
        int size = _ARRAYSIZE(entries);
        out = "Succesfully read: " + to_string(size);// Is always 0
}

所以我的问题是,我做错了什么?我在 2 个进程之间共享相同的结构,我正在为要写入的条目分配新内存并复制大小为 10 * sizeof(Entry); 的内存。在尝试读取时,我还尝试读取 10 * sizeof(Entry); 字节并将数据转换为 Entry*。有什么我想念的吗?欢迎所有帮助。

最佳答案

根据粗略的检查,这段代码似乎试图将包含 std::string 的结构映射到共享内存中,以供另一个进程使用。

不幸的是,这场冒险还没开始就注定了。即使您让数组长度正确传递,我也希望另一个进程会立即崩溃,只要它闻到另一个进程试图映射到共享内存段的 std::string .

std::string 是非常重要的类。 std::string 维护指向保存实际字符串数据的缓冲区的内部指针;缓冲区在堆上分配。

你确实明白 sizeof(std::string) 不会改变,无论字符串包含五个字符,还是《 war 与和平》的全部内容,对吧?停下来想一想,这怎么可能,只需要几个字节就可以存储一个 std::string

一旦你想一想,就会清楚为什么将一个进程的 std::string 映射到一个共享内存段,然后试图由另一个进程获取它们是不会工作。

唯一可以实际映射到/从共享内存映射的是plain old data ;尽管在某些情况下您也可以摆脱聚合。

关于c++ WINAPI 共享内存结构数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37890631/

相关文章:

c++ - 逐行改进 C++ 的读取文件?

c++ - 解码哈夫曼树

windows - 如何让 Windows 上的 Git 忽略符号链接(symbolic link)

windows - 如何将日期附加到 xcopy 中的目录路径

python - c++ 执行时间比 python 慢

c++ - std::fill 的 Clang 静态参数导致链接器失败

perl - 这是构建利用数组的 Perl 哈希的正确方法吗?

c - 如何释放分配的内存?

c++ - 为什么 C++ 中的参数匹配会忽略数组大小?

windows - 在 Windows XP 中创建 shell 替换的正确方法是什么?