You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kev/Drawer/IPCLib/SharedMemoryStruct.cs

150 lines
4.5 KiB
C#

1 month ago
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System;
using System.Runtime.InteropServices;
namespace IPCLib
{
// SharedMemoryStruct.cs - 最终修复版
/// <summary>
/// 共享内存头部结构(控制区)
/// ✅ 所有字段都是值类型,无引用类型
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct SharedMemoryHeader
{
public int IsLocked;
public long A_LastHeartbeat;
public long B_LastHeartbeat;
public long A_SessionId;
public long B_SessionId;
public int A_HasData;
public int B_HasData;
public int A_DataLength;
public int B_DataLength;
public long A_SequenceId;
public long B_SequenceId;
public int ConnectionStatus;
public long Reserved1;
public long Reserved2;
public long Reserved3;
public long Reserved4;
}
/// <summary>
/// 数据包结构1024 字节)
/// ✅ 修复:使用固定大小缓冲区替代数组
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct DataPacket
{
public long Timestamp; // 8 字节
public int DataType; // 4 字节
public int DataLength; // 4 字节
public long SequenceId; // 8 字节
// ✅ 修复使用固定大小缓冲区1000 字节)
public fixed byte Data[1000]; // 固定缓冲区,不是引用类型
}
/// <summary>
/// 内存布局常量
/// </summary>
public static class MemoryLayout
{
public const int HeaderSize = 256;
public const int PacketSize = 1024;
public const int AToBOffset = HeaderSize;
public const int BToAOffset = HeaderSize + PacketSize;
public const int TotalSize = HeaderSize + PacketSize * 2;
}
/// <summary>
/// 辅助工具类
/// </summary>
public static class SharedMemoryHelper
{
/// <summary>
/// 将字符串写入固定缓冲区
/// </summary>
public static unsafe void WriteToFixedBuffer(byte* buffer, string text, int maxLength = 1000)
{
// 清空缓冲区
for (int i = 0; i < maxLength; i++)
{
buffer[i] = 0;
}
if (string.IsNullOrEmpty(text))
return;
byte[] bytes = Encoding.UTF8.GetBytes(text);
int copyLength = Math.Min(bytes.Length, maxLength);
for (int i = 0; i < copyLength; i++)
{
buffer[i] = bytes[i];
}
}
/// <summary>
/// 从固定缓冲区读取字符串
/// </summary>
public static unsafe string ReadFromFixedBuffer(byte* buffer, int length)
{
if (length <= 0)
return string.Empty;
int actualLength = Math.Min(length, 1000);
byte[] bytes = new byte[actualLength];
for (int i = 0; i < actualLength; i++)
{
bytes[i] = buffer[i];
}
return Encoding.UTF8.GetString(bytes);
}
/// <summary>
/// 将字符串转换为字节数组(用于非 unsafe 场景)
/// </summary>
public static byte[] StringToBytes(string text, int maxLength = 1000)
{
if (string.IsNullOrEmpty(text))
return new byte[maxLength];
byte[] bytes = Encoding.UTF8.GetBytes(text);
byte[] result = new byte[maxLength];
Array.Copy(bytes, result, Math.Min(bytes.Length, maxLength));
return result;
}
/// <summary>
/// 将字节数组转换为字符串
/// </summary>
public static string BytesToString(byte[] bytes, int length)
{
if (bytes == null || length <= 0)
return string.Empty;
return Encoding.UTF8.GetString(bytes, 0, Math.Min(length, bytes.Length));
}
}
public enum ConnectionStatus
{
Disconnected = 0, // 断开(硬断开,不可恢复)
Connecting = 1, // 连接中
Connected = 2, // 正常连接
Warning = 3, // ⚠️ 警告:心跳延迟(可恢复)
SoftDisconnected = 4, // 🔄 软断开:超时但未确认退出(可恢复)
Frozen = 5 // ❄️ 死机:长时间无响应
}
}