我使用函数CreateFileMapping
MapViewOfFile
UnmapViewOfFile
在磁盘上创建共享块。我可以在这个块上放置一个新的类对象吗?
我使用VS2003 IDE。
try
{
Sphere *pData = m_pBVH->GetFirstHalfData();
Sphere *p = new(pData)Sphere(center, radius, index);
}
catch (std::exception& e)
{
// Can't catch
}
放置新错误:
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
在Debug
模式下,placement new
运算符可能会导致语法错误。这很可能是因为上面的代码,然后再次尝试再试一次!
在Release
模式下,它没关系,但抛出异常而不是std :: bad_alloc,无法弄清楚它是什么。也许存在共享内存的构建方式。我的共享内存创建代码如下:
CBVHVertexBuffer::CBVHVertexBuffer(const CString &file, unsigned int size)
{
this->file = file;
this->size = size;
fileHandle = INVALID_HANDLE_VALUE;
mapHandle = INVALID_HANDLE_VALUE;
mapLength = 0;
start = NULL;
end = NULL;
head = NULL;
tail = NULL;
fileHandle = ::CreateFile(
file,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_DELETE_ON_CLOSE,
NULL);
if (fileHandle != INVALID_HANDLE_VALUE)
{
//::SetFilePointer(fileHandle, size * pickingVertexSize, NULL, FILE_BEGIN);
//::SetEndOfFile(fileHandle);
//mapLength = ::GetFileSize(fileHandle, NULL);
//mapLength = size * pickingVertexSize;
mapHandle = ::CreateFileMapping(fileHandle, NULL, PAGE_READWRITE, 0, size * pickingVertexSize, NULL);
mapLength = ::GetFileSize(fileHandle, NULL);
start = (Sphere*)::MapViewOfFile(mapHandle, FILE_MAP_WRITE, 0, 0, 0);
}
end = start + size;
Clear();
}
答案 0 :(得分:3)
我建议只在映射文件中使用普通旧数据(POD),因为在映射和取消映射文件时指针可能无效
答案 1 :(得分:2)
原则上,您可以使用placement new operator(void* operator new (std::size_t size, void* ptr) throw();
)在已分配的内存缓冲区中创建对象。
但是,应在POD对象中应用在文件映射区域中创建对象。不建议将任何原始指针成员(以及虚拟内存表(如果有))存储在映射文件中,因为只要映射在不同的地址空间中完成,它们就会失效。在这种情况下,您还应该注意管理内存分配。
我建议看看boost进程间库(它们对memory mapped files有很好的支持,包括内存缓冲区的管理 - 分配算法,对象跟踪和用于链接对象地址空间的类指针类独立的(offset_ptr))。