簡體   English   中英

讀取 Memory Memory 映射文件 C++ 和 ZD7EFA19FBE7D39724FD5ADB60242

[英]Read Memory Memory Mapped File C++ and C#

我正在嘗試使用 memory 映射文件共享從 C++ 到 C# 的結構。 到目前為止,我設法在文件上寫入,但我無法讀取 C# 中的內容。

  1. 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;
} 
  1. 試圖讀取 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或您的操作系統等效項。

現在,一旦您將 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM