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

Windows平台Python与C++共享内存交互实现示例请求

Problem Cause

On Windows, Qt's QSharedMemory automatically prefixes the provided key with a namespace derived from the application's executable path to avoid naming collisions. This means even if you use the same key string in your C++ and Python programs, the actual native shared memory names will differ, leading to cross-process access failure.

Solution: Use Native Keys

To bypass Qt's automatic key transformation, use the setNativeKey() method to specify the exact Windows shared memory name. On Windows, you can prefix the name with Global\\ for cross-user session access, or Local\\ for the current user session (default if no prefix).

C++ Implementation

#include <QSharedMemory>
#include <QDebug>
#include <cstring>

int main(int argc, char** argv)
{
    QSharedMemory memory;
    // Use a global native key for cross-process access
    memory.setNativeKey("Global\\StreamSharedMemory");

    // Create or attach to shared memory (1MB size)
    if (!memory.create(1024 * 1024)) {
        if (memory.error() == QSharedMemory::AlreadyExists) {
            if (!memory.attach()) {
                qDebug() << "Attach failed:" << memory.errorString();
                return 1;
            }
            qDebug() << "Attached to existing shared memory";
        } else {
            qDebug() << "Create failed:" << memory.errorString();
            return 1;
        }
    } else {
        qDebug() << "Created new shared memory";
    }

    // Example: Write sample data to shared memory
    if (memory.isAttached()) {
        char* data = static_cast<char*>(memory.data());
        const char* sample = "Data from C++ service";
        std::strncpy(data, sample, memory.size());
    }

    // Keep process running to test Python access
    qDebug() << "Press Enter to exit...";
    std::getchar();

    memory.detach();
    return 0;
}

Python Implementation

from PyQt5.QtCore import QSharedMemory
import sys

memory = QSharedMemory()
# Match the same native key used in C++
memory.setNativeKey("Global\\StreamSharedMemory")

if not memory.attach():
    print(f"Attach failed: {memory.errorString()}")
    sys.exit(1)

# Example: Read data from shared memory
data_ptr = memory.data()
if data_ptr:
    raw_data = data_ptr.toByteArray().data()
    message = raw_data.decode('utf-8').strip('\x00')
    print(f"Received data: {message}")

memory.detach()
Alternative: Windows API Direct Implementation

If you prefer using raw Windows API instead of Qt, here are cross-process compatible examples:

C++ with Windows API

#include <windows.h>
#include <iostream>
#include <cstring>

int main() {
    const wchar_t* shm_name = L"Global\\WinAPISharedMemory";
    const size_t shm_size = 1024 * 1024;

    // Create or open shared memory mapping
    HANDLE h_map = CreateFileMappingW(
        INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, shm_size, shm_name
    );
    if (!h_map) {
        std::cout << "CreateFileMapping failed: " << GetLastError() << std::endl;
        return 1;
    }

    // Map view of the shared memory
    char* p_buf = static_cast<char*>(MapViewOfFile(
        h_map, FILE_MAP_ALL_ACCESS, 0, 0, shm_size
    ));
    if (!p_buf) {
        std::cout << "MapViewOfFile failed: " << GetLastError() << std::endl;
        CloseHandle(h_map);
        return 1;
    }

    // Write sample data
    const char* sample = "Data from Windows API C++";
    std::strncpy(p_buf, sample, shm_size);

    std::cout << "Press Enter to exit..." << std::endl;
    std::getchar();

    // Cleanup
    UnmapViewOfFile(p_buf);
    CloseHandle(h_map);
    return 0;
}

Python with ctypes

import ctypes
from ctypes import wintypes

# Load Windows kernel32 library
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)

# Define API functions and types
CreateFileMappingW = kernel32.CreateFileMappingW
CreateFileMappingW.argtypes = [wintypes.HANDLE, wintypes.LPCVOID, wintypes.DWORD, wintypes.DWORD, wintypes.DWORD, wintypes.LPCWSTR]
CreateFileMappingW.restype = wintypes.HANDLE

MapViewOfFile = kernel32.MapViewOfFile
MapViewOfFile.argtypes = [wintypes.HANDLE, wintypes.DWORD, wintypes.DWORD, wintypes.DWORD, wintypes.SIZE_T]
MapViewOfFile.restype = wintypes.LPVOID

UnmapViewOfFile = kernel32.UnmapViewOfFile
UnmapViewOfFile.argtypes = [wintypes.LPCVOID]
UnmapViewOfFile.restype = wintypes.BOOL

CloseHandle = kernel32.CloseHandle
CloseHandle.argtypes = [wintypes.HANDLE]
CloseHandle.restype = wintypes.BOOL

# Constants
INVALID_HANDLE_VALUE = wintypes.HANDLE(-1).value
PAGE_READWRITE = 0x04
FILE_MAP_ALL_ACCESS = 0x000F001F

# Shared memory configuration
shm_name = "Global\\WinAPISharedMemory"
shm_size = 1024 * 1024

# Open shared memory
h_map = CreateFileMappingW(INVALID_HANDLE_VALUE, None, PAGE_READWRITE, 0, shm_size, shm_name)
if not h_map:
    print(f"CreateFileMapping failed: {ctypes.get_last_error()}")
    exit(1)

# Map view to memory
p_buf = MapViewOfFile(h_map, FILE_MAP_ALL_ACCESS, 0, 0, shm_size)
if not p_buf:
    print(f"MapViewOfFile failed: {ctypes.get_last_error()}")
    CloseHandle(h_map)
    exit(1)

# Read and print data
raw_data = ctypes.string_at(p_buf)
message = raw_data.decode('utf-8').strip('\x00')
print(f"Received data: {message}")

# Cleanup
UnmapViewOfFile(p_buf)
CloseHandle(h_map)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 18:50:26