【问题标题】:Can Only Write Char* to LPVOID buffer?只能将 Char* 写入 LPVOID 缓冲区吗?
【发布时间】:2020-03-20 23:57:48
【问题描述】:

所以,我有一个文件映射对象(64KB)和该映射的视图(在偏移量 0 处也是 64KB)。

当我写视图时,我先写要写的数据的长度,然后再写数据(这样我就可以通过先读长度,再读那个字节数来读取数据)

出于某种原因,此代码仅在写入 16KB 之前的偏移量时才有效(使用 16383 的偏移量有效,16384 出现内存冲突)。

代码如下:

LIB_EXPORT bool mem_write_to_view(mem_mapview_p view, DWORD offset, unsigned char *bytes, int len)
{
    __try
    {
        ((LPDWORD)(view->data))[offset] = len; // access violation only on this line; if I remove this line, it will write all the way up to 64KB
        int sizeOfLen = sizeof(DWORD) / sizeof(char);
        for (int i = 0; i < len; i++)
        {
            ((char *)(view->data))[i + offset + sizeOfLen] = bytes[i];
        }
    }
    __except (GetExceptionCode() == EXCEPTION_IN_PAGE_ERROR ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_EXECUTION)
    {
        printf("ERROR: error\r\n");
        report_last(view->reporter, "mem_write_to_view");
        report_last_explicit(view->reporter, "mem_write_to_view", "Failed to write to view.");
        return false;
    }
    return true;
}

正如代码中的注释所示,当我尝试设置长度时,我只会遇到访问冲突(在 16KB 之后,再次,这在 16KB 之前有效,我不知道为什么),否则,我可以使用这种方法一直写到地图视图的末尾(因此这个问题的标题“只能将 char* 写入 LPVOID 缓冲区”)

view-&gt;data 用这一行初始化: view-&gt;data = MapViewOfFile(map-&gt;hMap, FILE_MAP_ALL_ACCESS, offset_hi, offset_lo, size); 在调用 mem_write_to_view 之前。

知道为什么会发生这种情况(更具体地说,为什么它只发生在 16KB+ 的偏移量处)?

我在MapViewOfFile 返回的 LPVOID 指针上运行了VirtualQuery,并确认它的大小确实为 64KB。

我真的对低级内存访问一无所知(我来自高级面向对象的背景),所以我不知道将LPVOID 解释为LPDWORD 可能会导致什么问题然后将其解释为char *,但我很确定这是在数据前面写入长度的唯一方法,对吧?

【问题讨论】:

    标签: c pointers casting


    【解决方案1】:

    DWORD 是 4 个字节,LPDWORD 是一个指向 DWORD 的指针,所以它上面的算术指针按 4 缩放。所以当你这样做时:

    ((LPDWORD)(view->data))[offset] = len;
    

    它将偏移量乘以 4 以获得要写入的字节地址。这意味着当偏移量为 16384 时,它会将 64KB 写入块中——刚好超过末尾。

    你可能想要什么

    *(LPDWORD)((char *)view->data + offset) = len;
    

    为了使偏移量以字节为单位(未缩放)。

    【讨论】:

    • Ohhhhh duh... 有道理。非常感谢
    • 我不能也只是将偏移量除以 4(或 sizeof(DWORD)
    • 可以,只要偏移量始终是 4 的倍数。出于对齐原因,您可能仍需要这样做(x86 允许非对齐访问,但效率低于对齐)
    • 嗯,我希望每个视图有 8 个 8KB 小节/“页面”,这样应该没问题。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 2021-11-02
    • 2017-01-05
    • 2018-12-31
    • 2015-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-01
    相关资源
    最近更新 更多