MapViewOfFileEx ファイルマッピングオブジェクトをメモリ上にマップする

Cの宣言:

LPVOID MapViewOfFileEx(
	HANDLE hMap,
	DWORD AccessMode,
	DWORD OffsetHigh,
	DWORD OffsetLow,
	DWORD MapSize,
	VOID BaseAddress);

説明:

hMapで指定したファイルマッピングオブジェクトをメモリ上にマップし、マップしたメモリ領域へのポインタを返す。

本関数は、マップするメモリ上の位置を指定可能であるほかは、MapViewOfFileと同様の機能を持つ。

マップするメモリ上の位置は引数のBaseAddressで指定する。その他の引数の意味および戻り値については、MapViewOfFileを参照。

BaseAddressに指定可能なメモリ位置は、メモリのメモリ割当て単位のサイズに整列されたものでなければならない。BaseAddressにNULLを指定した場合、MapViewOfFileExはMapViewOfFileと同等の動作をする。

95の場合、他の全ての32bitプロセス内のlpBaseAddressが指すメモリ領域がファイルマッピングオブジェクトに対して有効である場合のみ、関数の実行に成功する。

Cのサンプル:

下記サンプルでは、ファイルに保存されているツリー構造のデータを管理する。サンプルが起動されるたびに、ツリーにノードを追加する。ノードクラスのnew演算子において、ファイルマッピングオブジェクトのビュー上にノードのメモリ領域を確保することにより、ファイル上のデータであることを意識せずに、データを操作することができる。
#define STRICT

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

const char *MAPPED_FILE_NAME = "Test File Mapping Object";
const char *MUTEX_NAME = "Test Mutex Object";

const int CHILD_MAX = 20;

typedef struct {
	int NodeNum;
	int HeapSize;
	BYTE Heap[1];
} MAPPED_FILE_DATA;

MAPPED_FILE_DATA *pView;

class Node {
public:
	int NodeNo;
	int ChildNum;
	Node *Childs[CHILD_MAX];
	
	void AddChild(Node *child);
	void DispTree(bool bros, char *prefix);
	void *operator new(size_t size);
	Node();
};

void *Node::operator new(size_t size)
{
	void *p;

	p = &pView->Heap[pView->HeapSize];
	pView->HeapSize += size;

	return p;
}

Node::Node()
{
	ChildNum = 0;
	NodeNo = pView->NodeNum++;
}

void Node::AddChild(Node *child)
{
	Childs[ChildNum++] = child;
}

void Node::DispTree(bool bros, char *prefix)
{
	char child_prefix[1000];
	int i;

	printf("%s|\n%s+--%02d\n", prefix, prefix, NodeNo);
	if(!bros) sprintf(child_prefix, "%s    ", prefix);
	else sprintf(child_prefix, "%s|   ", prefix);

	for(i=0; i<ChildNum; i++) {

		Childs[i]->DispTree((i < ChildNum-1), child_prefix);
	}
}

int main()
{
	Node *RootNode;
	Node *NewNode;
	Node *CurrentNode;

	HANDLE hFile;
	HANDLE hMap;
	BOOL bAlreadyExisting;

	hFile = CreateFile("nodes.dat", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL);
	bAlreadyExisting = (GetLastError() == ERROR_ALREADY_EXISTS);
	hMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, sizeof(MAPPED_FILE_DATA), "test file mapping object");
	pView = (MAPPED_FILE_DATA *)MapViewOfFileEx(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0, (void *)0x00900000);
	CloseHandle(hFile);

	if(!bAlreadyExisting) {
		pView->NodeNum = 0;	
		pView->HeapSize = 0;
		RootNode = new Node;
	} else {
		RootNode = (Node *)&pView->Heap[0];
	}

	srand(time(NULL));

	CurrentNode = RootNode;
	while(CurrentNode->ChildNum>0) {
		if((rand() % 10) <2) break;
		CurrentNode = CurrentNode->Childs[rand() % CurrentNode->ChildNum];
	}
	
	NewNode = new Node;
	CurrentNode->AddChild(NewNode);

	RootNode->DispTree(false, "");

	UnmapViewOfFile(pView);
	CloseHandle(hMap);

	return 0;
}

メモ:
以下は実行例。実行するたびに、ノードが増えていく。

|
+--00
    |
    +--01
        |
        +--02
        |   |
        |   +--03
        |   |   |
        |   |   +--04
        |   |
        |   +--05
        |   |
        |   +--06
        |   |   |
        |   |   +--09
        |   |   |
        |   |   +--10
        |   |   |
        |   |   +--11
        |   |
        |   +--07
        |   |   |
        |   |   +--12
        |   |       |
        |   |       +--13
        |   |       |
        |   |       +--14
        |   |       |
        |   |       +--15
        |   |
        |   +--08
        |   |   |
        |   |   +--18
        |   |
        |   +--17
        |
        +--16

(original text:1999/02/19 更新)

本ドキュメントの内容は保証しません。本ドキュメントによって生じた結果について、一切の責任を負いません。