C# 通过共享内存的方式给python传递一张图片
C# 通过共享内存的方式给Python传递一张图片
简介: 需求是需要传到python中一张图片,然后通过python进行处理,我想到了一种进程间通信的方法,共享内存,我的理解就是开辟一块内存,A向内存里面写数据,B再去读取这块内存的数据。
C# 主程序代码
using System;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Text;
using System.Diagnostics;
using HalconDotNet;
class Program
{
static void Main()
{
// 共享内存名称
string sharedMemoryName = "TestSharedMemory";
HImage hImage = new HImage(@"F:\test1.bmp");
// 要传递的数据
string message = "Hello from C#! 这是来自C#的消息。";
int number = 12345;
double value = 3.14159;
Console.WriteLine("C#程序启动...");
Console.WriteLine($"要发送的消息: {message}");
Console.WriteLine($"要发送的整数: {number}");
Console.WriteLine($"要发送的浮点数: {value}");
// 创建共享内存
using (MemoryMappedFile mmf = MemoryMappedFile.CreateOrOpen(sharedMemoryName, 1024))
using (MemoryMappedViewAccessor accessor = mmf.CreateViewAccessor())
{
// 写入字符串
byte[] messageBytes = Encoding.UTF8.GetBytes(message);
accessor.Write(0, messageBytes.Length); // 在位置0写入字符串长度
accessor.WriteArray(4, messageBytes, 0, messageBytes.Length); // 从位置4开始写入字符串
// 写入整数(位置100)
accessor.Write(100, number);
// 写入浮点数(位置104)
accessor.Write(104, value);
// 写入完成标志(位置112)
accessor.Write(112, 1);
Console.WriteLine("\n数据已写入共享内存!");
// 启动Python程序
StartPythonProgram();
Console.WriteLine("按任意键退出...");
Console.ReadKey();
}
}
static void StartPythonProgram()
{
try
{
// 获取当前目录
string currentDir = Directory.GetCurrentDirectory();
string pythonScriptPath = @"C:\Users\Administrator\Desktop\pythonProject3\main.py";
Console.WriteLine($"正在启动Python脚本: {pythonScriptPath}");
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = "python";
start.Arguments = $"\"{pythonScriptPath}\"";
start.UseShellExecute = false;
start.RedirectStandardOutput = true;
start.RedirectStandardError = true;
start.CreateNoWindow = true;
int index = 1;
while(true)
{
using (Process process = Process.Start(start))
{
// 读取Python输出
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
process.WaitForExit();
if (!string.IsNullOrEmpty(output))
Console.WriteLine($"Python输出:\n{output}");
if (!string.IsNullOrEmpty(error))
Console.WriteLine($"Python错误:\n{error}");
}
}
}
catch (Exception ex)
{
Console.WriteLine($"启动Python程序失败: {ex.Message}");
Console.WriteLine("请确保Python已安装并在PATH环境变量中");
}
}
}
C# 代码
using System;
using System.IO.MemoryMappedFiles;
using System.Runtime.InteropServices;
using HalconDotNet;
public class SharedMemorySender
{
public unsafe void SendHObject(HObject image, string mapName = "HalconImageSharedMem")
{
MemoryMappedFile mmf = null;
MemoryMappedViewAccessor accessor = null;
try
{
// 获取图像指针和基本信息
HOperatorSet.GetImagePointer1(image, out HTuple pointer, out HTuple type, out HTuple width, out HTuple height);
// 计算图像数据大小
int pixelSize = GetPixelSize(type);
int imageDataSize = width.I * height.I * pixelSize;
// 创建内存映射文件 (大小 = 图像数据 + 4个int头部信息)
int headerSize = sizeof(int) * 4;
int totalSize = headerSize + imageDataSize;
mmf = MemoryMappedFile.CreateNew(mapName, totalSize);
// 获取访问器并写入头部信息
accessor = mmf.CreateViewAccessor();
int offset = 0;
// 明确指定类型
accessor.Write(offset, width.I);
offset += sizeof(int);
accessor.Write(offset, height.I);
offset += sizeof(int);
accessor.Write(offset, pixelSize);
offset += sizeof(int);
// 将类型字符串转换为整数编码
int typeCode = GetTypeCode(type.S);
accessor.Write(offset, typeCode);
offset += sizeof(int);
// 将图像数据拷贝到共享内存 - 使用不安全上下文
byte* source = (byte*)pointer.L;
for (int i = 0; i < imageDataSize; i++)
{
accessor.Write(offset + i, source[i]);
}
Console.WriteLine($"图像已写入共享内存: {width}x{height}, 类型: {type}, 大小: {imageDataSize}字节");
Console.WriteLine("按任意键退出...");
Console.ReadKey();
}
finally
{
accessor?.Dispose();
mmf?.Dispose();
}
}
private int GetPixelSize(HTuple imageType)
{
switch (imageType.S)
{
case "byte": return 1;
case "uint2": return 2;
case "int4": return 4;
default: throw new ArgumentException($"不支持的图像类型: {imageType}");
}
}
private int GetTypeCode(string typeString)
{
switch (typeString)
{
case "byte": return 1;
case "uint2": return 2;
case "int4": return 4;
default: return 1; // 默认byte
}
}
}
Python代码
import mmap
import struct
index = 1
def read_shared_memory():
try:
print("Python程序启动...")
print("正在读取共享内存...")
# 打开共享内存
# 注意:在Windows上使用命名共享内存,在Linux上使用文件映射
mm = mmap.mmap(-1, 1024, tagname='TestSharedMemory', access=mmap.ACCESS_READ)
# 读取字符串长度(4字节整数)
str_length_bytes = mm.read(4)
str_length = struct.unpack('I', str_length_bytes)[0] # 'I' 表示无符号整数
# 读取字符串内容
string_data = mm.read(str_length).decode('utf-8')
# 跳转到整数位置(100)
mm.seek(100)
number_data = struct.unpack('i', mm.read(4))[0] # 'i' 表示有符号整数
# 读取浮点数(104)
mm.seek(104)
value_data = struct.unpack('d', mm.read(8))[0] # 'd' 表示双精度浮点数
# 读取完成标志(112)
mm.seek(112)
flag = struct.unpack('i', mm.read(4))[0]
mm.close()
print("\n从C#程序接收到的数据:")
print(f"字符串: {string_data}")
print(f"整数: {number_data}")
print(f"浮点数: {value_data}")
print(f"完成标志: {flag}")
# 返回成功信息
return "Python程序执行成功!"
except Exception as e:
error_msg = f"读取共享内存失败: {str(e)}"
print(error_msg)
return error_msg
def main():
# 你的主要逻辑
return "==" + str(index)
if __name__ == "__main__":
# result = read_shared_memory()
# print(f"\n执行结果: {result}")
index = index + 1
exit(main())
本文来自博客园,作者:杰西卡若,转载请注明原文链接:https://www.cnblogs.com/jiexiekaruo/p/19212970

浙公网安备 33010602011771号