C#和python端通信之使用共享内存

2024-06-21 06:04

本文主要是介绍C#和python端通信之使用共享内存,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、前言

    本篇主要实验通过使用共享内存实现C#端代码和python端代码之间的通信,主要目的是相较于直接传输较大的数据(例如图像数据),该方式更节省时间。

二、代码

C#端:

    创建了一个大小为1的共享内存,名为flag1,存放一个byte变量,初始写入0

    创建了一个大小为1的共享内存,名为done,存放一个byte变量,初始写入1

    创建了一个大小为1024 * 16的共享内存,名为result,存放一个string变量,初始写入""

     之后读取图像,并创建和写入至一个大小为960*640*4的共享内存,名为cam1,存放一个byte[]变量 , 然后 flag1 写入1,循环读取done内存,若为1,则将result 内存读取出为string 并显示textBox1

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;using System.Drawing.Imaging;
using System.IO.MemoryMappedFiles;
using System.Runtime.InteropServices;namespace testShareMemory
{public partial class Form1 : Form{public Form1(){InitializeComponent();}private void test_0(){// 读取图片string imagePath = "E:/cshape_test/testShareMemory/001.png";Bitmap bitmap = new Bitmap(imagePath);// 确保图片大小为960x640if (bitmap.Width != 960 || bitmap.Height != 640){Console.WriteLine("图片尺寸不符合要求,必须为960x640");return;}MemoryMappedFile mmfCam1 = MemoryMappedFile.CreateOrOpen("cam1", bitmap.Width * bitmap.Height * 4);MemoryMappedViewAccessor accessor = mmfCam1.CreateViewAccessor();BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);byte[] buffer = new byte[bitmapData.Stride * bitmapData.Height];Marshal.Copy(bitmapData.Scan0, buffer, 0, buffer.Length);accessor.WriteArray(0, buffer, 0, buffer.Length);bitmap.UnlockBits(bitmapData);// 创建共享内存 flag , 并写入1var flagMMF = MemoryMappedFile.CreateOrOpen("flag1", 1);var flagAccessor = flagMMF.CreateViewAccessor();byte flagToWrite = 1;flagAccessor.Write(0, flagToWrite);//创建共享内存 done , 并写入0var doneMMF = MemoryMappedFile.CreateOrOpen("done", 1);var doneAccessor = doneMMF.CreateViewAccessor();byte doneToWrite = 0;doneAccessor.Write(0, doneToWrite);//创建共享内存 result , 并写入""int res_lens = 1024 * 32;MemoryMappedFile mmfResult = MemoryMappedFile.CreateOrOpen("result", res_lens);MemoryMappedViewAccessor resAccessor = mmfResult.CreateViewAccessor();byte[] strBytes = Encoding.UTF8.GetBytes("");//resAccessor.Write(0, strBytes.Length); // 首先写入字符串长度resAccessor.WriteArray(0, strBytes, 0, strBytes.Length); // 然后写入字符串字节内容// 循环间隔1秒,读取共享内存bool done = false;int search_times = 0;while (!done){byte doneValue = doneAccessor.ReadByte(0);byte flagValue = flagAccessor.ReadByte(0);if (doneValue == 1 && flagValue == 2){// 读取共享内存"result"string result;// 读取字符串长度(前4个字节)int length = resAccessor.ReadInt32(0);// 创建字节数组来存储字符串数据byte[] buffer_str = new byte[length];// 从共享内存读取字符串数据resAccessor.ReadArray(4, buffer_str, 0, length);// 将字节数组转换为字符串string resultString = Encoding.UTF8.GetString(buffer_str);textBox1.Text = "查询到的结果为: " + resultString;done = true; // 设置标志,退出循环}else{// 等待一段时间再继续轮询System.Threading.Thread.Sleep(1000); // 等待1秒search_times++;if (search_times > 100){//Console.WriteLine("查询超时!"   );textBox1.Text = "查询超时!";break;}}}}private void Form1_Load(object sender, EventArgs e){test_0();}}
}

python端:

    循环读取flag1共享内存,若为1,则读取cam1数据,还原为图像数据,将2写入flag1,并将json字符串data写入result内存区,将1写入done,显示图像数据

# -*- coding: utf-8 -*-
"""
Created on Tue Feb 27 17:10:01 2024@author: WIN10
"""import os , cv2
import numpy as npfrom multiprocessing import shared_memory
import time
import structimport json# 创建/打开共享内存
def create_or_open_shared_memory(name, size):try:shm = shared_memory.SharedMemory(create=False, name=name)except FileNotFoundError:shm = shared_memory.SharedMemory(create=True, name=name, size=size)return shmdef main():flag_name = "flag1"cam1_name = "cam1"done_name = "done"# 图像大小width, height, channels = 960, 640, 4image_size = width * height * channelsflag_shm = create_or_open_shared_memory(flag_name, size=1)  # 1个字节,用 uint8flag_array = np.ndarray((1,), dtype= np.uint8  , buffer=flag_shm.buf)done_shm = create_or_open_shared_memory(done_name, size=1)done_array = np.ndarray((1,), dtype=np.uint8, buffer=done_shm.buf)# 初始化 cam1 共享内存cam1_shm = create_or_open_shared_memory(cam1_name, size=image_size)cam1_array = np.ndarray((height, width, channels), dtype=np.uint8, buffer=cam1_shm.buf)res_shm =  create_or_open_shared_memory("result", size= 1024*16 )while True:if flag_array[0] == 1:# 读取图像数据image_rgba = np.copy(cam1_array)img  = cv2.cvtColor(image_rgba, cv2.COLOR_RGBA2RGB)  #C#端的bitmap传过来的是4通道的,应该转为3通道# 将 2 写入 flagflag_array[0] = 2#写入 jason字符串到 resultdata = {"name": "Mario","age": 28,}json_str = json.dumps(data)json_bytes = json_str.encode('utf-8')res_shm.buf[:4] = struct.pack('i', len(json_bytes))res_shm.buf[4:4 + len(json_bytes)] = json_bytesdone_array[0] = 1  #done 区域写入1# 显示读取到的图像cv2.imshow('Shared Memory Image', img )cv2.waitKey(0)break# 每隔100毫秒检测一次time.sleep(0.1)# 关闭共享内存cam1_shm.close()flag_shm.close()res_shm.close()done_shm.close()if __name__=="__main__":main()

三、运行结果

   先运行C# ,再运行python端

python端结果,显示接受到的图像

C#端结果,显示收到python端写入的json字符串

这篇关于C#和python端通信之使用共享内存的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1080391

相关文章

Python的Darts库实现时间序列预测

《Python的Darts库实现时间序列预测》Darts一个集统计、机器学习与深度学习模型于一体的Python时间序列预测库,本文主要介绍了Python的Darts库实现时间序列预测,感兴趣的可以了解... 目录目录一、什么是 Darts?二、安装与基本配置安装 Darts导入基础模块三、时间序列数据结构与

Python正则表达式匹配和替换的操作指南

《Python正则表达式匹配和替换的操作指南》正则表达式是处理文本的强大工具,Python通过re模块提供了完整的正则表达式功能,本文将通过代码示例详细介绍Python中的正则匹配和替换操作,需要的朋... 目录基础语法导入re模块基本元字符常用匹配方法1. re.match() - 从字符串开头匹配2.

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

C#实现千万数据秒级导入的代码

《C#实现千万数据秒级导入的代码》在实际开发中excel导入很常见,现代社会中很容易遇到大数据处理业务,所以本文我就给大家分享一下千万数据秒级导入怎么实现,文中有详细的代码示例供大家参考,需要的朋友可... 目录前言一、数据存储二、处理逻辑优化前代码处理逻辑优化后的代码总结前言在实际开发中excel导入很

通过Docker容器部署Python环境的全流程

《通过Docker容器部署Python环境的全流程》在现代化开发流程中,Docker因其轻量化、环境隔离和跨平台一致性的特性,已成为部署Python应用的标准工具,本文将详细演示如何通过Docker容... 目录引言一、docker与python的协同优势二、核心步骤详解三、进阶配置技巧四、生产环境最佳实践

Python一次性将指定版本所有包上传PyPI镜像解决方案

《Python一次性将指定版本所有包上传PyPI镜像解决方案》本文主要介绍了一个安全、完整、可离线部署的解决方案,用于一次性准备指定Python版本的所有包,然后导出到内网环境,感兴趣的小伙伴可以跟随... 目录为什么需要这个方案完整解决方案1. 项目目录结构2. 创建智能下载脚本3. 创建包清单生成脚本4

Spring Security简介、使用与最佳实践

《SpringSecurity简介、使用与最佳实践》SpringSecurity是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架,本文给大家介绍SpringSec... 目录一、如何理解 Spring Security?—— 核心思想二、如何在 Java 项目中使用?——

springboot中使用okhttp3的小结

《springboot中使用okhttp3的小结》OkHttp3是一个JavaHTTP客户端,可以处理各种请求类型,比如GET、POST、PUT等,并且支持高效的HTTP连接池、请求和响应缓存、以及异... 在 Spring Boot 项目中使用 OkHttp3 进行 HTTP 请求是一个高效且流行的方式。

Python实现Excel批量样式修改器(附完整代码)

《Python实现Excel批量样式修改器(附完整代码)》这篇文章主要为大家详细介绍了如何使用Python实现一个Excel批量样式修改器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录前言功能特性核心功能界面特性系统要求安装说明使用指南基本操作流程高级功能技术实现核心技术栈关键函

python获取指定名字的程序的文件路径的两种方法

《python获取指定名字的程序的文件路径的两种方法》本文主要介绍了python获取指定名字的程序的文件路径的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 最近在做项目,需要用到给定一个程序名字就可以自动获取到这个程序在Windows系统下的绝对路径,以下