读取内存内存映射文件 C++ 和 C#
Read Memory Memory Mapped File C++ and C#
我正在尝试使用内存映射文件共享一个从 C++ 到 C# 的结构。到目前为止,我设法在文件上写入,但我无法读取 C# 中的内容。
- 在 C++ 中发送数据
struct Bus_1553 // this is the structure to send
{
string name;
int directions;
};
struct Bus_1553* p_1553; // set the pointer to it
HANDLE handle; // create the handle
// here we define the data to send
string name = "IFF";
int directions = 3;
bool startShare() // Open the shared memory
{
try
{
handle = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(Bus_1553), L"DataSend");
p_1553 = (struct Bus_1553*) MapViewOfFile(handle, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, sizeof(Bus_1553));
return true;
}
catch (...)
{
return false;
}
}
int main()
{
if (startShare() == true)
{
while (true)
{
if (p_1553 != 0) // populate the memory
{
p_1553->name = name;
p_1553->directions = directions;
}
else
puts("create shared memory error");
}
}
if (handle != NULL)
CloseHandle(handle);
return 0;
}
- 正在尝试用 C# 阅读
namespace sharedMemoryGET
{
class sharedMemoryGET
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct Bus_Data_1553
{
public string name;
public int directions; // which directions used
}
public static MemoryMappedFile mmf;
public static MemoryMappedViewStream mmfvs;
static public bool MemOpen() // open the mapped file
{
try
{
mmf = MemoryMappedFile.OpenExisting("DataSend");
return true;
}
catch
{
return false;
}
}
public static void readData()
{
if (MemOpen())
{
using (var accessor = mmf.CreateViewAccessor())
{
accessor.Read(0, out Bus_Data_1553 a);
Console.WriteLine(a.name);
Console.WriteLine(a.directions);
}
}
}
}
}
当要共享的结构中存在字符串时,出现以下错误:
指定的类型必须是不包含引用的结构。
当我删除字符串并仅共享 int 方向时,我得到的值为 0。有人可以帮我解决这个问题吗?
让我们先从C++版本的问题说起。我将其加粗以确保没有人忽略它,这非常重要:永远不要将指针写入磁盘
std::string
是一个指针(实际上是 2 个指针)的包装器,它根据需要为您处理分配和重新分配。您绝对不能将它们写入任何地方的“文件”,您必须改为写入这些指针的内容。
一种简单的方法(在 C 中很流行)是简单地定义一个足够大的缓冲区来保存您的数据,然后根据需要使用它:
struct Bus_1553 // this is the structure to send
{
char name[128];
int directions;
};
要写入 name
,请使用 strcpy_s
或等效的 OS。
现在,一旦您用 C++ 将此结构写入共享文件,用 C# 读取它就是让系统(编组器)将大量字节解码为有用的托管对象。您可以通过在结构和字段定义上使用属性来执行此操作:
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public struct Bus_Data_1553
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string name;
public int directions; // which directions used
}
此外,如果您正确使用编组器,则不需要 unsafe
。
我正在尝试使用内存映射文件共享一个从 C++ 到 C# 的结构。到目前为止,我设法在文件上写入,但我无法读取 C# 中的内容。
- 在 C++ 中发送数据
struct Bus_1553 // this is the structure to send
{
string name;
int directions;
};
struct Bus_1553* p_1553; // set the pointer to it
HANDLE handle; // create the handle
// here we define the data to send
string name = "IFF";
int directions = 3;
bool startShare() // Open the shared memory
{
try
{
handle = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(Bus_1553), L"DataSend");
p_1553 = (struct Bus_1553*) MapViewOfFile(handle, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, sizeof(Bus_1553));
return true;
}
catch (...)
{
return false;
}
}
int main()
{
if (startShare() == true)
{
while (true)
{
if (p_1553 != 0) // populate the memory
{
p_1553->name = name;
p_1553->directions = directions;
}
else
puts("create shared memory error");
}
}
if (handle != NULL)
CloseHandle(handle);
return 0;
}
- 正在尝试用 C# 阅读
namespace sharedMemoryGET
{
class sharedMemoryGET
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct Bus_Data_1553
{
public string name;
public int directions; // which directions used
}
public static MemoryMappedFile mmf;
public static MemoryMappedViewStream mmfvs;
static public bool MemOpen() // open the mapped file
{
try
{
mmf = MemoryMappedFile.OpenExisting("DataSend");
return true;
}
catch
{
return false;
}
}
public static void readData()
{
if (MemOpen())
{
using (var accessor = mmf.CreateViewAccessor())
{
accessor.Read(0, out Bus_Data_1553 a);
Console.WriteLine(a.name);
Console.WriteLine(a.directions);
}
}
}
}
}
当要共享的结构中存在字符串时,出现以下错误: 指定的类型必须是不包含引用的结构。
当我删除字符串并仅共享 int 方向时,我得到的值为 0。有人可以帮我解决这个问题吗?
让我们先从C++版本的问题说起。我将其加粗以确保没有人忽略它,这非常重要:永远不要将指针写入磁盘
std::string
是一个指针(实际上是 2 个指针)的包装器,它根据需要为您处理分配和重新分配。您绝对不能将它们写入任何地方的“文件”,您必须改为写入这些指针的内容。
一种简单的方法(在 C 中很流行)是简单地定义一个足够大的缓冲区来保存您的数据,然后根据需要使用它:
struct Bus_1553 // this is the structure to send
{
char name[128];
int directions;
};
要写入 name
,请使用 strcpy_s
或等效的 OS。
现在,一旦您用 C++ 将此结构写入共享文件,用 C# 读取它就是让系统(编组器)将大量字节解码为有用的托管对象。您可以通过在结构和字段定义上使用属性来执行此操作:
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public struct Bus_Data_1553
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string name;
public int directions; // which directions used
}
此外,如果您正确使用编组器,则不需要 unsafe
。