【问题标题】:Allocate Static Shared Memory using MapViewOfFile使用 MapViewOfFile 分配静态共享内存
【发布时间】:2017-11-11 12:21:00
【问题描述】:

如何将共享内存分配给如下所示的静态缓冲区,但使用 CreateFileMapping 和 MapViewOfFile。

#pragma data_seg(".ABC")
__declspec (dllexport) char buffer[10000]  = {0};
#pragma data_seg()
#pragma comment(linker, "-section:.ABC,rws")

目标是创建一个在 C++ 和 FORTRAN 应用程序之间共享的静态共享缓冲区,就像使用 data_seg 时所做的那样。在创建动态分配的缓冲区时,FORTRAN 变得很棘手,因为您需要取消引用指针,这也是可行的,但这不是我想要的。

【问题讨论】:

  • 真正的问题是什么?
  • 我们应该知道CreateFileMappingMapViewOfFile 是什么吗?
  • @JonathanMee:WinAPI 的函数:CreateFileMappingMapViewOfFile。 OP:你的目标是什么,与什么分享?您能否提供更多信息?
  • 目标是创建一个在 C++ 和 FORTRAN 应用程序之间共享的静态共享缓冲区,就像使用 data_seg 时所做的那样。在创建动态分配的缓冲区时,FORTRAN 变得很棘手,因为您需要取消引用指针,这也是可行的,但这不是我想要的。
  • @user3716892 是什么让您认为MapViewOfFile 会更好?您仍然会有一个指向动态分配内存的指针(在系统页面文件中)。它不会是静态的。

标签: c++ winapi shared-memory memory-mapped-files data-segment


【解决方案1】:

等效的 Win32 API 调用如下所示:

SECURITY_DESCRIPTOR sd;
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);

SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = &sd;
sa.bInheritHandle = FALSE;

HANDLE hMapping = CreateFileMapping(INVALID_HANDLE_VALUE, &sa, PAGE_READWRITE, 0, 10000, TEXT("ABC")); 
if (!hMapping) ... // error handling

char *buffer = (char*) MapViewOfFile(hMapping, FILE_MAP_WRITE, 0, 0, 10000);
if (!buffer) ... // error handling

// use buffer as needed... 

UnmapViewOfFile(buffer);
CloseHandle(hMapping);

两个应用程序都必须使用相同的 lpName 值调用 CreateFileMapping() 才能访问系统内核中的相同映射对象。无论哪个应用程序首先调用CreateFileMapping() 都会创建对象,而第二个应用程序将获得现有对象的句柄。然后,MapViewOfFile() 将调用进程内的内存访问映射到该对象。这样,两个应用程序都在使用彼此共享的内存。当一个应用程序将数据写入对象时,另一个应用程序会看到它。

【讨论】:

  • 我知道这是创建共享文件映射的方法,但问题是我不想要动态指针(char *buffer)。我想要的可能是不可能的。
  • @user:这没有多大意义。此答案中的指针 buffer 与问题中的 buffer 数组之间几乎没有区别。如果您绝对需要将文件映射对象作为数组访问,您可以轻松地将指针转换为对数组类型的引用。或者只是索引指针。 buffer[0] = 'A'; 对指针和数组都是合法的。
  • @IInspectable:你所说的对于 C 和 C++ 来说是正确的,但请记住,OP 是在询问 Fortran。
  • 如果 OP 难以从 FORTRAN 访问内存,为什么 C 或 C++ 中的编译时间类型很重要?这只是一块内存。我也不明白问题中文件映射对象和共享段之间的显着区别。两者都在一个地址上提供一块内存,该地址只有在运行时才知道。
  • 不同之处在于 FORTRAN 中的缓冲区数组可以通过一个公共块访问,该块与需要执行调用才能从 C 转换的指针缓冲区相对。我不想执行执行调用因为我正在尝试创建一个只处理变量声明的预编译器。
猜你喜欢
  • 2015-08-08
  • 2016-10-21
  • 2013-10-12
  • 1970-01-01
  • 2019-03-07
  • 2012-10-23
  • 2012-01-26
  • 1970-01-01
相关资源
最近更新 更多