gpt4 book ai didi

c# - 与从 C++ 到 C# 的内存映射文件共享链式结构

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:07:42 26 4
gpt4 key购买 nike

接着我的另一个问题here ,感谢这个社区,我已经能够将字符串从 C++ 共享到 C#。

但是,我需要更上一层楼,我需要使用内存映射共享从 C++ 到 C# 的链式结构。

在示例场景中:

我的 C++ 结构:

struct STRUCT_2
{
char Name[260];
};

struct STRUCT_1
{
void Init()
{
this->Count = 0;
this->Index = 0;
}

DWORD Count;
DWORD Index;
STRUCT_2 Table[256];
};

我试图将它“转移”到 C#:

[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
public unsafe struct STRUCT_2
{
[FieldOffset(0)]
public fixed char Name[260];
}

[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
public unsafe struct STRUCT_1
{
void Init()
{
this.Count = 0;
this.Index = 0;
}
[FieldOffset(0)]
public uint Count;
[FieldOffset(0)]
public uint Index;
[FieldOffset(100)]
[MarshalAs(UnmanagedType.LPStruct, SizeConst = 256)]
public STRUCT_2 Table;
}

这部分有效,基本上我可以看到 CountIndex 的值,但是我看不到值,甚至看不到 STRUCT_2 中的值.

我尝试过改变:

public STRUCT_2[] Table;

但是编译器告诉我:

“指定的类型必须是不包含引用的结构。”

所以我的问题是,如何在 C# 中使用 MemoryMappedFile 读取结构中的结构?

非常欢迎建议、想法或示例。

更新:

完整的 C# 可测试代码:

[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
public unsafe struct STRUCT_2
{
[FieldOffset(0)]
public fixed byte Name[260];
// Fix thanks to Ben Voigt
}

[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
public unsafe struct STRUCT_1
{
void Init()
{
this.Count = 0;
this.Index = 0;
}
[FieldOffset(0)]
public uint Count;
[FieldOffset(0)]
public uint Index;
[FieldOffset(100)]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
public STRUCT_2[] Table;
}

static void Main(string[] args)
{
MemoryMappedFileSecurity CustomSecurity = new MemoryMappedFileSecurity();
CustomSecurity.AddAccessRule(new System.Security.AccessControl.AccessRule<MemoryMappedFileRights>("everyone", MemoryMappedFileRights.FullControl, System.Security.AccessControl.AccessControlType.Allow));

var mappedFile = MemoryMappedFile.CreateOrOpen("Local\\STRUCT_MAPPING", 1024, MemoryMappedFileAccess.ReadWriteExecute, MemoryMappedFileOptions.None, CustomSecurity, System.IO.HandleInheritability.Inheritable);

using (var accessor = mappedFile.CreateViewAccessor())
{
STRUCT_1 data;

accessor.Read<STRUCT_1>(0, out data); // ERROR !
//The specified Type must be a struct containing no references.

Console.WriteLine(data.Count);
Console.WriteLine(data.Index);
}
}

最佳答案

检查一下。

在 Visual Studio 2017、Windows 7 x64 上测试。

写入和读取数据工作查找。

这对我来说也是很好的学习。

花些时间。

祝一切顺利!

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct STRUCT_2
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 260)]
public byte[] Name;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)]
public struct STRUCT_1
{
void Init()
{
this.Count = 0;
this.Index = 0;
}
public uint Count;
public uint Index;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] //! array size of 10.
public STRUCT_2 [] Table;
}

static void test3()
{

MemoryMappedFileSecurity CustomSecurity = new MemoryMappedFileSecurity();
CustomSecurity.AddAccessRule(new System.Security.AccessControl.AccessRule<MemoryMappedFileRights>
( "everyone"
, MemoryMappedFileRights.FullControl
, System.Security.AccessControl.AccessControlType.Allow));

using (var mappedFile = MemoryMappedFile.CreateOrOpen("Local\\STRUCT_MAPPING"
, 10 * 1024
, MemoryMappedFileAccess.ReadWriteExecute
, MemoryMappedFileOptions.None
, CustomSecurity
, System.IO.HandleInheritability.Inheritable))
{
using (var accessor = mappedFile.CreateViewAccessor())
{
//! test setting.
int table_count = 5;

//! write data.
STRUCT_1 write_data;
write_data.Index = 1;
write_data.Count = 2;
write_data.Table = new STRUCT_2[10];

for (int i = 0; i < 10; i++)
{
write_data.Table[i].Name = new byte[260];
write_data.Table[i].Name[0] = (byte)i;
}

//! ----------------------------
// Get size of struct
int size = Marshal.SizeOf(typeof(STRUCT_1));
byte[] data = new byte[size];

// Initialize unmanaged memory.
IntPtr p = Marshal.AllocHGlobal(size);

// Copy struct to unmanaged memory.
Marshal.StructureToPtr(write_data, p, false);

// Copy from unmanaged memory to byte array.
Marshal.Copy(p, data, 0, size);

// Write to memory mapped file.
accessor.WriteArray<byte>(0, data, 0, data.Length);

// Free unmanaged memory.
Marshal.FreeHGlobal(p);
p = IntPtr.Zero;

//! ----------------------------------------------
STRUCT_1 read_data;
size = Marshal.SizeOf(typeof(STRUCT_1));
data = new byte[size];

// Initialize unmanaged memory.
p = Marshal.AllocHGlobal(size);


// Read from memory mapped file.
accessor.ReadArray<byte>(0, data, 0, data.Length);

// Copy from byte array to unmanaged memory.
Marshal.Copy(data, 0, p, size);

// Copy unmanaged memory to struct.
read_data = (STRUCT_1)Marshal.PtrToStructure(p, typeof(STRUCT_1));

// Free unmanaged memory.
Marshal.FreeHGlobal(p);
p = IntPtr.Zero;


Console.WriteLine(read_data.Index);
Console.WriteLine(read_data.Count);
}
}
}

关于c# - 与从 C++ 到 C# 的内存映射文件共享链式结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47058825/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com