C#与C++交互开发系列(二十):跨进程通信之共享内存(Shared Memory)

news2024/11/26 8:51:46

在这里插入图片描述

1、前言

共享内存(Shared Memory)是一种高效的跨进程通信方式,尤其适用于同一台计算机上的进程之间的高速数据传输。与套接字相比,共享内存允许多个进程直接访问同一块内存区域,减少了数据传输的中间步骤,适合需要高性能和低延迟的场景。本文将介绍如何在 C# 和 C++ 之间通过共享内存实现跨进程通信,并附上完整的示例代码。

2、什么是共享内存?

共享内存是一种在操作系统中分配的内存区域,允许多个进程对该内存区域进行读写。不同于管道或套接字,数据不需要被复制到缓冲区中进行传输,而是直接由各个进程访问内存数据,从而提高了数据传输效率。

3、实现步骤

  1. C++ 进程:创建共享内存区域,将数据写入内存。
  2. C# 进程:打开该共享内存区域,从内存中读取数据。

4、示例代码

以下代码展示了一个 C++ 进程创建并写入共享内存,另一个 C# 进程读取该共享内存中的数据。

C++ 代码:创建并写入共享内存

使用 Windows API 创建共享内存,并将数据写入共享内存区域。

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

int main() {
    const char* sharedMemoryName = "Local\\MySharedMemory";
    const char* message = "Hello from C++!";

    // 创建共享内存
    HANDLE hMapFile = CreateFileMappingA(
        INVALID_HANDLE_VALUE,
        NULL,
        PAGE_READWRITE,
        0,
        256,
        sharedMemoryName
    );

    if (hMapFile == NULL) {
        std::cerr << "Could not create file mapping object: " << GetLastError() << std::endl;
        return 1;
    }

    // 映射内存
    LPVOID pBuf = MapViewOfFile(
        hMapFile,
        FILE_MAP_ALL_ACCESS,
        0,
        0,
        256
    );

    if (pBuf == NULL) {
        std::cerr << "Could not map view of file: " << GetLastError() << std::endl;
        CloseHandle(hMapFile);
        return 1;
    }

    // 写入数据到共享内存
    CopyMemory((PVOID)pBuf, message, strlen(message) + 1);

    std::cout << "Data written to shared memory: " << message << std::endl;
    std::cout << "Press Enter to exit...";
    std::cin.get();

    // 释放资源
    UnmapViewOfFile(pBuf);
    CloseHandle(hMapFile);

    return 0;
}

代码解析

  • CreateFileMappingA:创建共享内存对象。
  • MapViewOfFile:将共享内存映射到进程地址空间。
  • CopyMemory:将数据写入共享内存。
  • UnmapViewOfFileCloseHandle:释放内存映射并关闭句柄。

C# 代码:读取共享内存

在 C# 中使用 MemoryMappedFile 类打开并读取共享内存数据。

using System;
using System.IO.MemoryMappedFiles;
using System.Text;

class Program {
    static void Main() {
        const string sharedMemoryName = "Local\\MySharedMemory";

        // 打开共享内存
        using (MemoryMappedFile mmf = MemoryMappedFile.OpenExisting(sharedMemoryName)) {
            // 读取共享内存数据
            using (MemoryMappedViewAccessor accessor = mmf.CreateViewAccessor(0, 256)) {
                byte[] buffer = new byte[256];
                accessor.ReadArray(0, buffer, 0, buffer.Length);
                
                // 将字节数组转换为字符串
                string message = Encoding.ASCII.GetString(buffer).TrimEnd('\0');
                Console.WriteLine("Data read from shared memory: " + message);
            }
        }
    }
}

代码解析

  • MemoryMappedFile.OpenExisting:打开现有的共享内存对象。
  • MemoryMappedViewAccessor:创建内存视图以读取共享内存中的数据。
  • ReadArray:从共享内存中读取数据。
  • Encoding.ASCII.GetString:将字节数组转换为字符串。

5、运行步骤

  1. 编译并运行 C++ 程序,它将创建共享内存并写入数据。
  2. 运行 C# 程序,它将打开并读取共享内存中的数据。

运行结果:
在这里插入图片描述

  • C++ 程序输出:Data written to shared memory: Hello from C++!
  • C# 程序输出:Data read from shared memory: Hello from C++!

6、注意事项

  1. 命名空间一致性:确保共享内存名称一致,否则 C# 程序无法找到 C++ 程序创建的共享内存。
  2. 访问权限:共享内存的访问权限应当在 C++ 和 C# 之间保持一致。
  3. 数据格式:在多字节字符的处理上要确保编码一致,以免出现乱码。

7、应用场景

  • 高性能数据传输:适用于大数据量、低延迟的应用场景,如视频处理、游戏引擎等。
  • 跨进程数据共享:允许多个进程同时访问同一块数据,减少数据复制开销。

8、优缺点

  • 优点
    • 高速数据传输,适合大数据量传输场景。
    • 不需要数据序列化与反序列化,降低了性能开销。
  • 缺点
    • 只适用于同一台计算机上的进程通信。
    • 需要注意数据同步,避免多个进程同时写入导致的数据竞争。

9、总结

通过共享内存,C# 和 C++ 程序能够实现高效的跨进程通信,适用于高频、大数据量的数据传输需求。共享内存虽然具备较高的性能优势,但同时需要妥善管理访问权限和数据同步。

在下一篇文章中,我们将介绍 消息队列(Message Queues) 的实现方法,它更适合分布式系统中数据量不大但需要排队处理的场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2235129.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

萌熊数据科技:剑指脑机转入,开启科技新篇章

近日&#xff0c;科技圈传来一则令人瞩目的消息&#xff0c;天津萌熊数据科技有限公司和天津一万年科技发展有限公司在全国范围内大力开展AI加生命科学的主体业务&#xff0c;并明确将朝着脑机转入方向深入发展&#xff0c;引发了行业内外的广泛关注。 天津萌熊数据科技有限公司…

计算机网络:网络层 —— IP 多播技术

文章目录 基本概念IP多播地址和多播组 IP多播的类型硬件多播将IPv4多播地址映射为多播MAC地址 基本概念 多播&#xff08;Multicast&#xff0c;也称为组播&#xff09;是一种实现“一对多”通信的技术&#xff0c;允许一台或多台主机&#xff08;多播源&#xff09;发送单一数…

使用Markdown编写适用于GitHub的README.md文件的目录结构

文章目录 [toc] 顶部1. 使用[TOC]自动生成2. VSCode中的插件3. 手搓目录目录相关资料本文相关代码一、概述1.1 基本概念1.2 两种处理模型&#xff08;1&#xff09;微批处理&#xff08;2&#xff09;持续处理 1.3 Structured Streaming和Spark SQL、Spark Streaming关系 二、编…

旧衣回收小程序:提高回收效率,扩大服务范围

近年来&#xff0c;旧衣回收作为一种新兴回收模式&#xff0c;逐渐走入了大众的生活中&#xff0c;在回收市场中形成了新的商业模式&#xff0c;也为大众带来了新的创业选择。 随着社会生活的快速发展&#xff0c;人们的生活水平不断提高&#xff0c;为旧衣市场发展提供了基础…

0-基于图的组合优化算法学习(NeurIPS 2017)(未完)

文章目录 Abstract1 Introduction2 图上的贪婪算法的通用表述3 表示:图嵌入3.1 Structure2Vec3.2 参数化 Q ^ ( h ( S ) , v ; Θ ) \widehat{Q}(h(S), v; \Theta) Q ​(h(S),v;Θ)4 Training: Q-learningAbstract 为NP-hard组合优化问题设计好的启发式或近似算法通常需要大…

python验证码滑块图像识别

文章目录 1、案例图片1、需求说明2、代码实现总结 1、案例图片 1、需求说明 python 3.10,写一个滑块验证码的自动化程序。需要一个opencv的函数&#xff0c;能准确的计算&#xff0c;在这同一张图片上&#xff0c;滑块形状和缺口形状的坐标位置及两个形状之间在X轴上的距离。请…

Spring AI 核心概念

SpringAI 核心概念 1. Models2. Prompts3. Prompt Templates4. Embeddings5. Tokens6. Structured Output7. Bringing Your Data & APIs to the AI Model7.1 Retrieval Augmented Generation7.2 Function Calling 1. Models AI 模型是用于处理和生成信息的算法&#xff0c…

从0开始学习Linux——文本编辑器

往期目录&#xff1a; 1、从0开始学习Linux——Linux简介&安装 2、从0开始学习Linux——搭建属于自己的Linux系统 我们通过前面教程的学习已经了解了什么是Linux&#xff0c;并且我们也定制安装了属于我们自己的一个Linux系统。从这个章节开始我们将开始学习如何去操作Linu…

外包干了三年,精神严重内耗。。。

前段时间我同事&#xff08;做测试的一个妹子&#xff09;跟我讲&#xff0c;感觉早上起来十分的疲惫&#xff0c;不想上班&#xff0c;问我们这是什么样的现象&#xff0c;其实有时候我也有这种感觉&#xff0c;虽然我卷&#xff0c;但我也是肉体凡胎啊&#xff01;不是机器人…

华宇TAS应用中间件入围鲲鹏应用创新大赛2024全国总决赛

近日&#xff0c;鲲鹏应用创新大赛2024全国总决赛入围名单出炉。华宇TAS应用中间件经过区域赛、半决赛一路披荆斩棘&#xff0c;在众多优秀的解决方案中脱颖而出&#xff0c;成功入围全国总决赛。 这也表明华宇TAS应用中间件在方案创新性、技术领先性、商业前景、社会价值等方…

惊爆!内容创业新纪元:AI工作流助你打造自媒体帝国!

又是一个研究AI工作流的深夜。看着扣子商店里各种神奇的智能体,我不禁感叹技术的魔力。一个简单的工作流模板,居然能把过去需要一整天才能完成的工作,压缩到几分钟… 扣子模板 大家好,我是momo,一个专注教人使用AI工作流做自媒体的创业者。今天想和你分享一个能让内容创作效率…

史上最大应用层DDoS攻击 H2 Rapid Reset攻击研究

前言 2023年10月Cloudflare、Google、AWS等厂商公布了一种利用HTTP/2快速重置进行应用层DDoS攻击的0day漏洞(CVE-2023-44487)[1][2]&#xff0c;即H2 Rapid Reset DDoS。Google宣传其监控到此种攻击峰值超过每秒3.98亿个请求&#xff0c;打破互联网历史最大应用层DDoS攻击记录…

饱和限幅器MATLAB和CODESYS平台下的实现

1、博途PLC限幅器(SCL代码) 博途PLC限幅器(SCL代码)-CSDN博客文章浏览阅读182次。本文详细介绍了博途PLC的限幅器功能,包括饱和限幅器的概念,并提供了完整的SCL编程代码示例,帮助读者理解和应用PLC限幅器。https://rxxw-control.blog.csdn.net/article/details/136029196 …

在 CSS 中,gap 是 布局容器(flex 或 grid)的属性。它用于设置容器内子元素之间的间距。

在 CSS 中&#xff0c;gap 是 布局容器&#xff08;flex 或 grid&#xff09;的属性。它用于设置容器内子元素之间的间距。以下是 gap 属性在不同布局中的应用&#xff1a; 1. 在 CSS Grid 布局中 gap 定义了网格行和列之间的间距。可以分别使用 row-gap 和 column-gap 设置行…

JavaWeb项目-----博客系统

一.设计数据库 1.创建数据库 create database if not exists java108_blog_system character set utf8; drop table if exists user; drop table if exists blog;2.创建博客列表 create table blog(blogId int primary key auto_increment,title varchar(20),content varcha…

一文读懂:AIOps 从自动化运维到智能化运维

今天跟大家聊一聊AIOps&#xff08;人工智能运维&#xff09; 为了应对企业面临着日益复杂的运营挑战&#xff0c;AIOps&#xff08;人工智能运维&#xff09;作为一种创新的方法应运而生&#xff0c;结合了人工智能和机器学习技术&#xff0c;来提升IT运营的效率和性能。 这…

从0开始学习Linux——文件目录

往期目录&#xff1a; 从0开始学习Linux——简介&安装 从0开始学习Linux——搭建属于自己的Linux虚拟机 从0开始学习Linux——文本编辑器 从0开始学习Linux——Yum工具 从0开始学习Linux——远程连接工具 上期教程我们学习了如何使用远程连接工具去连接Linux系统&#xff0…

C++入门基础知识140—【关于C++ 类构造函数 析构函数】

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///C爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于C 类构造函数 & 析构函数的相关内容…

MSC“名实之辩”:精准鉴定只为精准治疗

前 言 MSC是一群来源广泛、能够体外增殖分化的异质性细胞。MSC具有免疫调节、促进组织修复等作用&#xff0c;应用于多种疾病的治疗。由于科学进程、习惯等原因&#xff0c;MSC具有多种名称。自先秦以来&#xff0c;就有“名实之辩”&#xff0c;今日我们就讲一讲MSC的名称与…

零基础 Vue 入门:个人主页完整示例教程” “Vue 实战:构建简洁美观的个人主页界面” “从零开始使用 Vue 构建个人主页,包含详细代码解析”

效果图 博客教程&#xff1a;使用 Vue 构建简易个人主页界面 目录 前言项目结构和准备HTML 与 CSS 布局Vue 数据绑定和渲染功能实现总结 前言 本教程将带你逐步使用 Vue.js 创建一个简易的“个人主页”界面。通过学习该项目&#xff0c;你将掌握 Vue 的基本数据绑定、指令的…