You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows平台C++与Python命名共享内存传图黑屏问题排查

问题分析与解决方案

核心问题:Windows下共享内存命名空间不兼容

Boost.Interprocess在Windows平台创建共享内存时,默认会将名称放入Local命名空间(前缀为Local\),而Python的mmap模块直接使用传入的名称时,不会自动添加该前缀,导致Python实际打开的是一个全新的空共享内存,因此读取到全0数据,显示黑屏。

分步修复方案

1. 统一共享内存命名规则

方案A:修改C++代码显式指定命名空间
在创建共享内存时,直接使用带Local\前缀的名称:

#define SHM_NAME "Local\\SharedMemory"

方案B:修改Python代码添加前缀
将Python中的共享内存名称改为:

SHM_NAME = "Local\\SharedMemory"

2. 修正BMP文件的读取逻辑

BMP文件包含54字节的文件头+信息头,直接写入整个文件会导致头部数据被当成像素值。需要只写入像素数据:
在C++代码中,读取文件时跳过前54字节:

// 跳过BMP文件头(54字节)
imageFile.seek(54);
// 再执行拷贝操作
auto end = std::copy(std::istreambuf_iterator<char>(imageFile), 
                     std::istreambuf_iterator<char>(), 
                     static_cast<char*>(region.get_address()));
// 验证写入字节数
size_t bytes_written = std::distance(std::istreambuf_iterator<char>(imageFile), end);
if (bytes_written != (BYTES_NUMBER - 54)) {
    std::cerr << "Failed to write full image data to shared memory." << std::endl;
    return 1;
}

同时注意调整BYTES_NUMBER为实际像素数据的大小(原文件大小-54)。

3. 匹配BMP的像素格式

BMP文件默认存储像素为BGR顺序,而你Python代码中指定的是RGB格式,这会导致颜色错乱甚至黑屏。修改Python代码的格式参数:

# 先按BGR读取,再转换为RGB
image = Image.frombytes("BGR", (IMAGE_WIDTH, IMAGE_HEIGHT), image_data, "raw").convert("RGB")

4. 验证共享内存数据完整性

在Python读取后,可以先检查数据是否全0:

if all(b == 0 for b in image_data):
    print("Error: Read all zero data from shared memory")
else:
    print(f"Read {len(image_data)} bytes, first 10 bytes: {image_data[:10]}")

修正后的完整代码示例

C++代码

#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <iostream>
#include <fstream>
#include <iterator>

using namespace boost::interprocess;
#define SHM_NAME "Local\\SharedMemory"
#define PIXEL_BYTES 541744 // 原文件大小541798 - 54字节头

int main()
{
    try {
        shared_memory_object shm(open_or_create, SHM_NAME, read_write);
        shm.truncate(PIXEL_BYTES);

        mapped_region region(shm, read_write);

        std::ifstream imageFile("input.bmp", std::ios::binary);
        if (!imageFile) {
            std::cerr << "Failed to open the image file." << std::endl;
            return 1;
        }

        // 跳过BMP文件头
        imageFile.seekg(54);
        if (!imageFile) {
            std::cerr << "Image file is too small to be a valid BMP." << std::endl;
            return 1;
        }

        auto start = std::istreambuf_iterator<char>(imageFile);
        auto end_iter = std::istreambuf_iterator<char>();
        auto copy_end = std::copy(start, end_iter, static_cast<char*>(region.get_address()));
        size_t bytes_written = std::distance(start, copy_end);

        if (bytes_written != PIXEL_BYTES) {
            std::cerr << "Only wrote " << bytes_written << " bytes, expected " << PIXEL_BYTES << std::endl;
            return 1;
        }

        imageFile.close();
        std::cout << "Image pixel data successfully written to shared memory." << std::endl;

        std::string command = "python sharedMemory.py";
        std::system(command.c_str());

        std::cout << "Press any key to exit." << std::endl;
        _getch();

        // 清理共享内存
        shared_memory_object::remove(SHM_NAME);
    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
        shared_memory_object::remove(SHM_NAME);
        return 1;
    }

    return 0;
}

Python代码

import mmap
from PIL import Image

SHM_NAME = "Local\\SharedMemory"
PIXEL_BYTES = 541744
IMAGE_WIDTH = 511
IMAGE_HEIGHT = 265

if __name__ == "__main__":
    try:
        shm = mmap.mmap(-1, PIXEL_BYTES, SHM_NAME)
        image_data = shm.read(PIXEL_BYTES)
        shm.close()

        if all(b == 0 for b in image_data):
            print("Error: Read all zero data from shared memory")
        else:
            # BMP像素是BGR顺序,转换为RGB显示
            image = Image.frombytes("BGR", (IMAGE_WIDTH, IMAGE_HEIGHT), image_data, "raw").convert("RGB")
            image.show()
    except Exception as e:
        print(f"Error: {e}")

内容的提问来源于stack exchange,提问作者am_289

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 09:35:44