b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

文件绝对路径 winapi?c 文件绝对路径 api?文件内存映射CreateFileMapping和GlobalA(2)

电脑杂谈  发布时间:2016-10-25 16:02:21  来源:网络整理

PBYTE pbFile = (PBYTE)MapViewOfFile(hFileMapping, // 将文件数据映射到进程的地址空间
FILE_MAP_ALL_ACCESS,(DWORD)(qwFileOffset>>32), (DWORD)(qwFileOffset&0xFFFFFFFF), dwBytesInBlock);

while(bLoop)
{
DWORD ret = WaitForMultipleObjects(2, hEvent, FALSE, INFINITE); // 捕获事件hEvent[0]和事件hEvent[1]
ret -= WAIT_OBJECT_0;
switch (ret)
{
case 0: // 接收数据事件触发
nReadLen=syio_Read(port[1], pbFile + qwFileOffset, QueueLen); // 从端口接收数据并保存到内存映射文件
qwFileOffset += nReadLen;
break;

case 1:
bLoop = FALSE;

UnmapViewOfFile(pbFile); // 从进程的地址空间撤消文件数据映像

CloseHandle(hFileMapping); // 关闭文件映射对象
break;
}
}

存在一个问题:在终止事件触发处理过程中如果只简单的执行UnmapViewOfFile()和CloseHandle()函数将无法正确标识文件的实际大小,即如果开辟的内存映射文件为30GB,而接收的数据只有14GB,那么上述程序执行完后,保存的文件长度仍是30GB。也就是说,在处理完成后还要再次通过内存映射文件的形式将文件恢复到实际大小,下面是实现此要求的主要代码:
hFile2 = CreateFile("Recv.zip", GENERIC_WRITE | GENERIC_READ,FILE_SHARE_READ, NULL,CREATE_ALWAYS,
FILE_FLAG_SEQUENTIAL_SCAN,NULL); // 创建另外一个文件内核对象

memcpy(pbFile2, pbFile, qwFileOffset); // 将数据从原来的内存映射文件复制到此内存映射文件
UnmapViewOfFile(pbFile); //从进程的地址空间撤消文件数据映像
UnmapViewOfFile(pbFile2);

CloseHandle(hFileMapping); // 关闭文件映射对象
CloseHandle(hFileMapping2);

DeleteFile("Recv1.zip"); // 删除临时文件

(4)如果是小批量数据,采用以上函数即可同样实现进程共享。

参考原文:

======================================================================================================================

VC中关于GlobalAlloc,GlobalLock,GlobalUnLock

(1)GlobalAlloc函数分配一块内存,该函数会返回分配的内存句柄。GlobalLock函数锁定内存块,该函数接受一个内存句柄作为参数,然后返回一个指向被锁定的内存块的指针,您可以用该指针来读写内存。GlobalUnlock函数来解锁先前被锁定的内存,该函数使得指向内存块的指针无效。GlobalFree函数来释放内存块,您必须传给该函数一个内存句柄。
(2)函数说明

A,GlobalAlloc,分配一个全局内存块,函数返回全局内存句柄。参数类型及说明:wFlags Long,对分配的内存类型进行定义的常数标志,如下所示:GMEM_FIXED 分配一个固定内存块;GMEM_MOVEABLE 分配一个可移动内存块等。Bytes Long,要分配的字符数。
注解:如指定了 GMEM_FIXED,那么返回值就是要使用的实际内存地址即指针(GlobalLock 会返回同样的值),所以在使用固定内存块的时候不需要执行一个 GlobalLock/GlobalUnlock 操作。
关于GlobalAlloc的问题。问:在使用 GlobalAlloc 分配一个全局内存块时,使用GMEM_FIXED分配一个固定内存块与使用GMEM_MOVEABLE分配一个可移动内存块到底有什么不同?其效率上是否也存在差异?
答:GMEM_MOVEABLE是允许操作系统(或者应用程序)实施对内存堆的管理,在必要时,操作系统可以移动内存块获取更大的块,或者合并一些空闲的内存块,也称“垃圾回收”,它可以提高内存的利用率。一般情况下,内存堆空间是由用户来管理的,windows操作系统不干预。如果存在下列情况,即堆中有10个1K的空闲块,这时如果直接申请一个5K的内存空间,会得到不成功的信息。但如果其它已经被占用的内存块是movable,这时系统就可以移动这些内存块,合并出一个5k的内存块,并成功分配给用户使用。它的空间效率是以时间效率为代价的。

B,GlobalLock,锁定一个全局的内存对象,返回指向该对象的第一个字节的指针。函数原型:LPVOID GlobalLock( HGLOBAL hMem ),
参数:hMem:全局内存对象的句柄。这个句柄是通过GlobalAlloc或GlobalReAlloc来得到的。返回值:调用成功返回指向该对象的第一个字节的指针;调用失败返回NULL,可以用GetLastError来获得出错信息。

C,GlobalUnlock,解除被锁定的全局内存对象。函数原型:BOOL GlobalUnlock( HGLOBAL hMem ),参数:hMem:全局内存对象句柄,
返回值:非零值,指定的内存对象仍处于被锁定状态;0,函数执行出错,可以用GetLastError来获得出错信息,如果返回NO_ERROR,则表示内存对象已经解锁了。注意:这个函数实际上是将内存对象的锁定计数器减一,如果计数器不为0,则表示执行过多个GlobalLock函数来对这个内存对象加锁,需要对应数目的GlobalUnlock函数来解锁。


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/tongxinshuyu/article-19414-2.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    • 昙翼
      昙翼

      说明美国不愿面对岛礁的12海里内是中国的了

    • 苗晓阳
      苗晓阳

      不是说美国是纸老虎吗

    热点图片
    拼命载入中...