C# 尝试读取C中的共享内存时出现堆栈溢出错误#

C# 尝试读取C中的共享内存时出现堆栈溢出错误#,c#,stack-overflow,shared-memory,C#,Stack Overflow,Shared Memory,以下代码生成堆栈溢出错误。它创建共享内存空间,然后尝试将共享内存内容复制到本地缓冲区。在非托管C++中我编写了几个程序,但是C语言对我来说是陌生的…我已经在堆上分配了一个缓冲区,正在尝试将共享内存缓冲区复制到本地缓冲区中。这是堆栈溢出错误触发的地方:accessor.Read(0,out ps.hi)。在将共享内存缓冲区复制到我提供的引用之前,accessor.Read函数可能会尝试创建共享内存缓冲区的本地副本?如果是这样的话,在C#中向共享内存传输大内存块和从共享内存传输大内存块的推荐方法是什

以下代码生成堆栈溢出错误。它创建共享内存空间,然后尝试将共享内存内容复制到本地缓冲区。在非托管C++中我编写了几个程序,但是C语言对我来说是陌生的…我已经在堆上分配了一个缓冲区,正在尝试将共享内存缓冲区复制到本地缓冲区中。这是堆栈溢出错误触发的地方:
accessor.Read(0,out ps.hi)。在将共享内存缓冲区复制到我提供的引用之前,
accessor.Read
函数可能会尝试创建共享内存缓冲区的本地副本?如果是这样的话,在C#中向共享内存传输大内存块和从共享内存传输大内存块的推荐方法是什么?我还没有发现这个问题,在我的互联网搜索,所以任何帮助将不胜感激

确切的错误消息是:“mscorlib.dll中发生了类型为'System.StackOverflowException'的未处理异常”

使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.IO;
使用System.IO.MemoryAppedFile;
使用系统线程;
命名空间控制台应用程序2
{
不安全结构我的结构
{
公共固定UInt16 img[1280*960];
}
班级计划
{
我的结构你好;
静态void Main(字符串[]参数)
{
程序ps=新程序();
ps.hi=新的my_struct();
使用(var mmf=MemoryMappedFile.CreateOrOpen(“OL_SharedMemSpace”,System.Runtime.InteropServices.Marshal.SizeOf(ps.hi)))
{
使用(var accessor=mmf.CreateViewAccessor())
{
//听事件。。。
EventWaitHandle请求事件;
EventWaitHandle ready_事件;
尝试
{
request_event=EventWaitHandle.OpenExisting(“OL_ReceiveEvent”);
}
捕获(WaitHandleCannotBeOpenedException)
{
WriteLine(“接收事件不存在…正在创建一个”);
request_event=neweventwaithandle(false,EventResetMode.AutoReset,“OL_ReceiveEvent”);
}
尝试
{
ready_event=EventWaitHandle.OpenExisting(“OL_ReadyEvent”);
}
捕获(WaitHandleCannotBeOpenedException)
{
WriteLine(“就绪事件不存在…正在创建一个”);
ready_event=neweventwaithandle(false,EventResetMode.AutoReset,“OL_ReceiveEvent”);
}
System.Console.WriteLine(“确定…准备好执行命令…”);
while(true)
{
读(0,输出ps.hi);
request_event.WaitOne();
}
}
}
}
}

}

您的
ps.hi=new my_struct()未将数据放置在堆上

C#struct始终是一种值类型,在本例中是一种非常大的值类型。太大了。
在2*1280*960时,它将超出默认1MB堆栈


我不熟悉MMF API,但看起来您应该能够将其作为
uint[]
数组来阅读,而不需要周围的结构

也许这会有帮助。这里是C++本土作家:

#include <windows.h>
#include <memory>

const int BUFFER_SiZE = sizeof(uint8_t) * 1024 * 1024;
const wchar_t MMF_NAME[] = L"Global\\SharedMemoryExample";

int main()
{
    wprintf(L"Shared Memory example. Native writer\r\n"); 
    wprintf(L"BUFFER_SIZE: %d bytes\r\n", BUFFER_SiZE);
    wprintf(L"MMF name: %s\r\n", MMF_NAME);

    HANDLE hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, BUFFER_SiZE, MMF_NAME);
    if (hMapFile == NULL)
    {
        wprintf(L"CreateFileMapping failed with error: %d", GetLastError());
        return -1;
    }
    std::shared_ptr<void> mapHandleGuard(hMapFile, &::CloseHandle);
    uint8_t* pBuffer = (uint8_t*)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, BUFFER_SiZE);
    if (pBuffer == NULL)
    {
        wprintf(L"MapViewOfFile failed with error: %d", GetLastError());
        return -2;
    }
    std::shared_ptr<void> bufferGuard(pBuffer, &::UnmapViewOfFile);

    wprintf(L"Press 'Enter' to write some data to shared memory");
    getchar();

    // Write magic data :)
    memset(pBuffer, 0xFA, BUFFER_SiZE);

    wprintf(L"Press 'Enter' close application");
    getchar();

    return 0;
}
#包括
#包括
const int BUFFER_SiZE=sizeof(uint8_t)*1024*1024;
常量wchar\u t MMF\u NAME[]=L“全局\\SharedMemoryExample”;
int main()
{
wprintf(L“共享内存示例.本机编写器\r\n”);
wprintf(L“缓冲区大小:%d字节\r\n”,缓冲区大小);
wprintf(L“MMF名称:%s\r\n”,MMF\u名称);
HANDLE hMapFile=CreateFileMapping(无效的句柄值,NULL,页读写,0,缓冲区大小,MMF名称);
if(hMapFile==NULL)
{
wprintf(L“CreateFileMapping失败,错误为:%d”,GetLastError());
返回-1;
}
std::shared_ptr mapHandleGuard(hMapFile,&::CloseHandle);
uint8\u t*pBuffer=(uint8\u t*)映射视图文件(hMapFile,FILE\u MAP\u ALL\u ACCESS,0,0,BUFFER\u SiZE);
如果(pBuffer==NULL)
{
wprintf(L“MapViewOfFile失败,错误为:%d”,GetLastError());
返回-2;
}
std::shared_ptr bufferGuard(pBuffer,&::UnmapViewOfFile);
wprintf(L“按Enter键将一些数据写入共享内存”);
getchar();
//写入魔法数据:)
memset(pBuffer,0xFA,缓冲区大小);
wprintf(L“按下‘输入’关闭应用程序”);
getchar();
返回0;
}
下面是.NET阅读器:

class Program
    {
        private const string MMF_NAME = "Global\\SharedMemoryExample";
        const int BUFFER_SIZE = sizeof(byte) * 1024 * 1024;

        static void Main(string[] args)
        {
            try
            {
                Console.WriteLine("Shared Memory example. .NET reader");
                Console.WriteLine("BUFFER_SIZE: {0} bytes", BUFFER_SIZE);
                Console.WriteLine("MMF name: {0}", MMF_NAME);

                Console.WriteLine("Press 'Enter' to open Shared memory");
                Console.ReadLine();

                using (var mmf = System.IO.MemoryMappedFiles.MemoryMappedFile.OpenExisting(MMF_NAME))
                {
                    Console.WriteLine("{0} was opened.", MMF_NAME);

                    using (var accessor = mmf.CreateViewAccessor())
                    {
                        Console.WriteLine("ViewAccessor was created.");

                        byte[] buffer = new byte[BUFFER_SIZE];

                        Console.WriteLine("Press 'Enter' to read from Shared memory");
                        Console.ReadLine();

                        int cntRead = accessor.ReadArray(0, buffer, 0, BUFFER_SIZE);
                        Console.WriteLine("Read {0} bytes", cntRead);

                        if (IsBufferOk(buffer, cntRead))
                            Console.WriteLine("Buffer is ok");
                        else
                            Console.WriteLine("Buffer is bad!");
                    }
                }
            }
            catch(Exception  ex)
            {
                Console.WriteLine("Got exception: {0}", ex);
                Console.ReadLine();
            }
        }
        private static bool IsBufferOk(byte[] buffer, int length)
        {
            for(int i = 0; i < length; i++)
            {
                if (buffer[i] != 0XFA)
                    return false;
            }
            return true;
        }
    }
类程序
{
私有常量字符串MMF\u NAME=“全局\\SharedMemoryExample”;
常量int BUFFER_SIZE=sizeof(字节)*1024*1024;
静态void Main(字符串[]参数)
{
尝试
{
WriteLine(“共享内存示例..NET阅读器”);
WriteLine(“缓冲区大小:{0}字节”,缓冲区大小);
WriteLine(“MMF名称:{0}”,MMF_名称);
Console.WriteLine(“按“回车”打开共享内存”);
Console.ReadLine();
使用(var mmf=System.IO.MemoryMappedFile.MemoryMappedFile.OpenExisting(mmf_NAME))
{
WriteLine(“{0}已打开。”,MMF_NAME);
使用(var accessor=mmf.CreateViewAccessor())
{
WriteLine(“创建了ViewAccessor”);
字节[]缓冲区=新字节[缓冲区大小];
Console.WriteLine(“按“回车”从共享内存读取”);
Console.ReadLine();
int cntRead=accessor.ReadArray(0,缓冲区,0,缓冲区大小);
WriteLine(“读取{0}字节”,cntRead);
if(IsBufferOk(缓冲区,cntRead))
Console.WriteLine(“缓冲区正常”);
其他的
WriteLine(“缓冲区坏了!”);
}
class Program
    {
        private const string MMF_NAME = "Global\\SharedMemoryExample";
        const int BUFFER_SIZE = sizeof(byte) * 1024 * 1024;

        static void Main(string[] args)
        {
            try
            {
                Console.WriteLine("Shared Memory example. .NET reader");
                Console.WriteLine("BUFFER_SIZE: {0} bytes", BUFFER_SIZE);
                Console.WriteLine("MMF name: {0}", MMF_NAME);

                Console.WriteLine("Press 'Enter' to open Shared memory");
                Console.ReadLine();

                using (var mmf = System.IO.MemoryMappedFiles.MemoryMappedFile.OpenExisting(MMF_NAME))
                {
                    Console.WriteLine("{0} was opened.", MMF_NAME);

                    using (var accessor = mmf.CreateViewAccessor())
                    {
                        Console.WriteLine("ViewAccessor was created.");

                        byte[] buffer = new byte[BUFFER_SIZE];

                        Console.WriteLine("Press 'Enter' to read from Shared memory");
                        Console.ReadLine();

                        int cntRead = accessor.ReadArray(0, buffer, 0, BUFFER_SIZE);
                        Console.WriteLine("Read {0} bytes", cntRead);

                        if (IsBufferOk(buffer, cntRead))
                            Console.WriteLine("Buffer is ok");
                        else
                            Console.WriteLine("Buffer is bad!");
                    }
                }
            }
            catch(Exception  ex)
            {
                Console.WriteLine("Got exception: {0}", ex);
                Console.ReadLine();
            }
        }
        private static bool IsBufferOk(byte[] buffer, int length)
        {
            for(int i = 0; i < length; i++)
            {
                if (buffer[i] != 0XFA)
                    return false;
            }
            return true;
        }
    }