CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VB >  基础类

再论 "在VB中用文件映射来进行进程通讯"

楼主derway()2004-08-04 18:18:14 在 VB / 基础类 提问

网上发布的一个篇关于<在VB中用文件映射来进行进程通讯>的文章,这篇文章提供了原代码,但是我把它搞到VB里头运行,但是点击   manage   那个程序的时候,老是说"采样程序未运行!"始终实现不了它所说的效果.   我看了一下,好像那个映射文件的句柄   Maphandle   的值为0.  
   
  DiskFileName   =   "D:\Article\Mapping\Sample"    
  MapFileName   =   DiskFileName   &   "Map"    
   
  我觉得代码中上面这两行的下面一行好像有点问题.  
   
  我VB还不是很熟,请各位大侠指教,下面我给出那一份程序的代码,看一下能不能现实真正的数据传递. 问题点数:0、回复次数:17Top

1 楼derway()回复于 2004-08-04 18:20:15 得分 0

在VB中用文件映射来进行进程通讯  
   
  当我们用VB开发应用系统时,可能涉及多进程问题。比如工业上应用较多的数据采集系统,也许就需要两个进程,一个是“采样程序”,另一个是“管理程序”,“采样程序”做单一的采集样本工作,而“管理程序”则对样本进行分析,存储,输出各种图表等等。为了便于维护,“采样程序”与“管理程序”各自作为独立的应用程序而运行,那么“管理程序”怎样才能取得“采样程序”所采集的数据呢?这就是所谓进程间的通信问题。    
  在多个应用程序之间交换数据,我们自然会想到磁盘文件,但这种方法在实时系统中是不宜采用的,因为读写磁盘文件的时间效率往往不能满足实时要求。幸运的是,Windows提供了几种高效的进程间交换数据的机制,如管道,邮路和文件映射。以下我们只针对文件映射进行讨论。    
  一.   文件映射概念    
  所谓文件映射,简单地说,就是将磁盘文件(或部分)映射到某段内存空间,对磁盘文件的访问转变成对内存的访问,显然,这大大提高了访问速度。    
  实际的映射过程是通过几个API函数来实现的,首先需要创建一个“文件映射对象”,而这个对象是共享的,各个进程可将对象映射到自己的内存地址空间,各进程的映射地址不一定相同,但地址中的内容却一定是相同的,各进程对各自的映射地址的访问都归结为对“文件映射对象”的访问。    
  如上所言,我们可以认为“文件映射”是将文件映射到内存供各进程共享。那我们何不直接开辟一块全局内存来共享呢?这在32位Windows中是行不通的,因为全局内存在32位Windows中不是多进程共享的对象。因此,文件映射在进程间通信中扮演了重要的角色。    
  二.   示例    
  我们姑且把这个示例叫做“数据采集系统”,它由两个工程组成:Sampling.vbp(采样)和Manage.vbp(管理)。    
  Sampling.vbp包含两个文件:Form1.frm,Module1.bas。清单如下:    
  Form1.frm:    
  VERSION   5.00    
  Begin   VB.Form   Form1    
  Caption   =   "Sampling"    
  ClientHeight   =   1440    
  ClientLeft   =   48    
  ClientTop   =   288    
  ClientWidth   =   4416    
  LinkTopic   =   "Form1"    
  ScaleHeight   =   1440    
  ScaleWidth   =   4416    
  StartUpPosition   =   3   '窗口缺省    
  Begin   VB.CommandButton   cmdStop    
  Caption   =   "Stop"    
  Enabled   =   0   'False    
  Height   =   372    
  Left   =   2160    
  TabIndex   =   2    
  Top   =   360    
  Width   =   972    
  End    
  Begin   VB.CommandButton   cmdStart    
  Caption   =   "Start"    
  Height   =   372    
  Left   =   840    
  TabIndex   =   1    
  Top   =   360    
  Width   =   972    
  End    
  Begin   VB.TextBox   Text1    
  Height   =   372    
  Left   =   120    
  TabIndex   =   0    
  Text   =   "Text1"    
  Top   =   840    
  Width   =   4092    
  End    
  Begin   VB.Timer   Timer1    
  Enabled   =   0   'False    
  Interval   =   60    
  Left   =   0    
  Top   =   0    
  End    
  End    
  Attribute   VB_Name   =   "Form1"    
  Attribute   VB_GlobalNameSpace   =   False    
  Attribute   VB_Creatable   =   False    
  Attribute   VB_PredeclaredId   =   True    
  Attribute   VB_Exposed   =   False    
   
  Top

2 楼derway()回复于 2004-08-04 18:41:53 得分 0

Option   Explicit    
       
  Private   Sub   cmdStart_Click()    
  Pub_Timer1Run   =   False    
  Pub_LastTime   =   Timer()    
  Timer1.Enabled   =   True    
  cmdStart.Enabled   =   False    
  cmdStop.Enabled   =   True    
  End   Sub    
       
  Private   Sub   cmdStop_Click()    
  Timer1.Enabled   =   False    
  cmdStart.Enabled   =   True    
  cmdStop.Enabled   =   False    
  End   Sub    
       
  Private   Sub   Form_Load()    
  Call   CreateMap    
  End   Sub    
       
  Private   Sub   Form_Unload(Cancel   As   Integer)    
  Call   CloseMap    
  End   Sub    
       
  Private   Sub   Timer1_Timer()    
  Static   tm   As   Single,   Dlt   As   Single    
  Static   i   As   Integer    
  Static   dtNow   As   Date    
  Static   S   As   String    
  Static   v(1   To   Pub_LoopN)   As   Single    
       
  If   Pub_Timer1Run   Then   Exit   Sub    
  Pub_Timer1Run   =   True    
       
  tm   =   Timer():   dtNow   =   Now()    
  Dlt   =   tm   -   Pub_LastTime    
  If   Sgn(Dlt)   =   -1   Then   '两次时间跨午夜0点    
  Dlt   =   Dlt   +   86400!   '86400   =   24   *   3600    
  End   If    
       
  Do   While   Dlt   >=   Pub_Period    
  Pub_LastTime   =   tm    
  Call   GetV(v())    
  Call   GetFromMap(strBuffer)    
  If   Left(strBuffer,   1)   =   "*"   Then    
  S   =   "   "   &   Format(dtNow,   Pub_FormatDT)    
  For   i   =   1   To   Pub_LoopN    
  S   =   S   &   "   "   &   Format(v(i),   Pub_FormatV)    
  Next   i    
  strBuffer   =   S:   Call   CopyToMap(strBuffer)    
  Text1.Text   =   S    
  Else    
  'Add   to   File    
  End   If   'Left(strBuffer,   1)   =   "*"    
  Exit   Do    
  Loop    
       
  Pub_Timer1Run   =   False    
  End   Sub   'Timer1_Timer    
       
  Private   Sub   GetV(v()   As   Single)    
  Const   MaxV   =   4000!    
  Dim   i   As   Integer    
       
  Randomize    
  For   i   =   1   To   Pub_LoopN    
  v(i)   =   CSng(MaxV   *   Rnd)    
  Next   i    
  End   Sub   'GetV    
       
  Module1.bas:    
  Attribute   VB_Name   =   "Module1"    
  Option   Explicit    
  #Const   Sampling   =   True   '编译常数Sampling=Ture:采样,   =False:管理    
  Public   DiskFileName   As   String   '实时样本磁盘文件名    
  Public   MapFileName   As   String   '前者的(内存)映射文件名    
  Public   FileHandle   As   Long   '磁盘文件句柄    
  Public   MapHandle   As   Long   '映射文件句柄    
  Public   MapAddress   As   Long   '映射地址    
  Public   strBuffer   As   String   '实时样本缓冲    
  Public   LenBuffer   As   Long   '缓冲区长度    
       
  Public   Const   Pub_LoopN   =   2   '通道数目    
  Public   Const   Pub_FormatDT   =   "yyyy-mm-dd   hh:mm:ss"   '日期/时间格式    
  Public   Const   Pub_FormatV   =   "0000.000"   '样本数据格式    
  Public   Pub_LenDT   As   Long   '日期/时间宽度    
  Public   Pub_LenV   As   Long   '样本数据宽度    
       
  Public   Const   Pub_Period   =   2!   '采样周期(秒)    
  Public   Pub_LastTime   As   Single   '上次采样时间    
  Public   Pub_Timer1Run   As   Boolean   '中断例程在运行标志    
       
  Public   Const   FILE_MAP_WRITE   =   &H2    
  Public   Const   FILE_MAP_READ   =   &H4    
  Public   Const   PAGE_READWRITE   =   4&    
  Public   Const   GENERIC_READ   =   &H80000000    
  Public   Const   GENERIC_WRITE   =   &H40000000    
  Public   Const   CREATE_ALWAYS   =   2    
  Public   Const   FILE_SHARE_READ   =   &H1    
  Public   Const   FILE_SHARE_WRITE   =   &H2    
  Public   Const   FILE_ATTRIBUTE_NORMAL   =   &H80    
       
  Declare   Function   lstrcpyn   Lib   "kernel32"   Alias   "lstrcpynA"   _    
  (DesStr   As   Any,   _    
  SrcStr   As   Any,   _    
  ByVal   MaxLen   As   Long)   As   Long    
  Declare   Function   CloseHandle   Lib   "kernel32"   (ByVal   hObject   As   Long)   As   Long    
  #If   Sampling   Then    
  Declare   Function   CreateFile   Lib   "kernel32"   Alias   "CreateFileA"   _    
  (ByVal   lpFileName   As   String,   _    
  ByVal   dwDesiredAccess   As   Long,   _    
  ByVal   dwShareMode   As   Long,   _    
  ByVal   lpSecurityAttributes   As   Long,   _    
  ByVal   dwCreationDisposition   As   Long,   _    
  ByVal   dwFlagsAndAttributes   As   Long,   _    
  ByVal   hTemplateFile   As   Long)   As   Long    
  Declare   Function   WriteFile   Lib   "kernel32"   _    
  (ByVal   hFile   As   Long,   _    
  lpBuffer   As   Any,   _    
  ByVal   nNumberOfBytesToWrite   As   Long,   _    
  lpNumberOfBytesWritten   As   Long,   _    
  ByVal   lpOverlapped   As   Long)   As   Long    
  Declare   Function   FlushFileBuffers   Lib   "kernel32"   (ByVal   hFile   As   Long)   As   Long    
  #End   If    
  #If   Sampling   Then    
  Declare   Function   CreateFileMapping   Lib   "kernel32"   Alias   "CreateFileMappingA"   _    
  (ByVal   hFile   As   Long,   _    
  ByVal   lpFileMappingAttributes   As   Long,   _    
  ByVal   flProtect   As   Long,   _    
  ByVal   dwMaximumSizeHigh   As   Long,   _    
  ByVal   dwMaximumSizeLow   As   Long,   _    
  ByVal   lpName   As   String)   As   Long    
  #Else    
  Declare   Function   OpenFileMapping   Lib   "kernel32"   Alias   "OpenFileMappingA"   _    
  (ByVal   dwDesiredAccess   As   Long,   _    
  ByVal   bInheritHandle   As   Long,   _    
  ByVal   lpName   As   String)   As   Long    
  #End   If    
  Declare   Function   MapViewOfFile   Lib   "kernel32"   _    
  (ByVal   hFileMappingObject   As   Long,   _    
  ByVal   dwDesiredAccess   As   Long,   _    
  ByVal   dwFileOffsetHigh   As   Long,   _    
  ByVal   dwFileOffsetLow   As   Long,   _    
  ByVal   dwNumberOfBytesToMap   As   Long)   As   Long    
  Declare   Function   UnmapViewOfFile   Lib   "kernel32"   _    
  (lpBaseAddress   As   Any)   As   Long    
  '    
  Public   Sub   InitVar()    
  DiskFileName   =   "D:\Article\Mapping\Sample"    
  MapFileName   =   DiskFileName   &   "Map"    
  Pub_LenDT   =   Len(Pub_FormatDT)    
  Pub_LenV   =   Len(Pub_FormatV)    
  LenBuffer   =   1   +   Pub_LenDT   +   (Pub_LenV   +   1)   *   Pub_LoopN    
  strBuffer   =   String(LenBuffer   +   1,   "*")    
  FileHandle   =   0    
  MapHandle   =   0    
  MapAddress   =   0    
  End   Sub   'InitVar    
       
  Public   Sub   CopyToMap(S   As   String)    
  If   MapAddress   <>   0   Then    
  Call   lstrcpyn(ByVal   MapAddress,   ByVal   S,   LenBuffer   +   1)    
  End   If    
  End   Sub    
       
  Public   Sub   GetFromMap(S   As   String)    
  If   MapAddress   <>   0   Then    
  Call   lstrcpyn(ByVal   S,   ByVal   MapAddress,   LenBuffer   +   1)    
  End   If    
  End   Sub    
       
  Public   Sub   CloseMap()    
  If   MapAddress   <>   0   Then    
  Call   UnmapViewOfFile(ByVal   MapAddress)    
  MapAddress   =   0    
  End   If    
  If   MapHandle   <>   0   Then    
  Call   CloseHandle(MapHandle)    
  MapHandle   =   0    
  End   If    
  If   FileHandle   <>   0   Then    
  Call   CloseHandle(FileHandle)    
  FileHandle   =   0    
  End   If    
  End   Sub   'CloseMap    
  Top

3 楼derway()回复于 2004-08-04 18:42:25 得分 0

#If   Sampling   Then    
       
  Public   Sub   CreateMap()    
  Dim   w   As   Long    
       
  Call   InitVar    
  FileHandle   =   CreateFile(DiskFileName,   _    
  GENERIC_WRITE   Or   GENERIC_READ,   _    
  FILE_SHARE_READ   Or   FILE_SHARE_WRITE,   _    
  0,   _    
  CREATE_ALWAYS,   _    
  FILE_ATTRIBUTE_NORMAL,   _    
  0)    
  Call   WriteFile(FileHandle,   ByVal   strBuffer,   LenBuffer   +   1,   w,   0)    
  Call   FlushFileBuffers(FileHandle)    
       
  MapHandle   =   CreateFileMapping(FileHandle,   _    
  0,   _    
  PAGE_READWRITE,   _    
  0,   _    
  0,   _    
  MapFileName)    
  MapAddress   =   MapViewOfFile(MapHandle,   FILE_MAP_WRITE,   0,   0,   0)    
  End   Sub   'CreateMap    
       
  #Else    
       
  Public   Function   OpenMap()   As   Long    
  Call   InitVar    
  OpenMap   =   0    
  MapHandle   =   OpenFileMapping(FILE_MAP_WRITE,   False,   MapFileName)    
  If   MapHandle   =   0   Then   Exit   Function    
  MapAddress   =   MapViewOfFile(MapHandle,   FILE_MAP_WRITE,   0,   0,   0)    
  If   MapAddress   =   0   Then    
  Call   CloseHandle(MapHandle)    
  MapHandle   =   0    
  End   If    
  OpenMap   =   MapAddress    
  End   Function   'OpenMap    
       
  #End   If   'Sampling    
       
  Manage.vbp也包含两个文件:Form1.frm,Module1.bas。清单如下:    
  Form1.frm:    
  VERSION   5.00    
  Begin   VB.Form   Form1    
  Caption   =   "Manage"    
  ClientHeight   =   1440    
  ClientLeft   =   48    
  ClientTop   =   288    
  ClientWidth   =   4416    
  LinkTopic   =   "Form1"    
  ScaleHeight   =   1440    
  ScaleWidth   =   4416    
  StartUpPosition   =   3   '窗口缺省    
  Begin   VB.CommandButton   cmdStart    
  Caption   =   "Start"    
  Height   =   372    
  Left   =   1560    
  TabIndex   =   1    
  Top   =   240    
  Width   =   972    
  End    
  Begin   VB.TextBox   Text1    
  Height   =   372    
  Left   =   120    
  TabIndex   =   0    
  Text   =   "Text1"    
  Top   =   840    
  Width   =   4092    
  End    
  Begin   VB.Timer   Timer1    
  Enabled   =   0   'False    
  Interval   =   60    
  Left   =   0    
  Top   =   0    
  End    
  End    
  Attribute   VB_Name   =   "Form1"    
  Attribute   VB_GlobalNameSpace   =   False    
  Attribute   VB_Creatable   =   False    
  Attribute   VB_PredeclaredId   =   True    
  Attribute   VB_Exposed   =   False    
  Option   Explicit    
       
  Private   Sub   cmdStart_Click()    
  If   OpenMap()   =   0   Then    
  MsgBox   "采样程序未运行!",   vbOKOnly,   ""    
  Exit   Sub    
  End   If    
       
  Pub_Timer1Run   =   False    
  Timer1.Enabled   =   True    
  cmdStart.Enabled   =   False    
  End   Sub    
       
  Private   Sub   Form_Unload(Cancel   As   Integer)    
  Call   CloseMap    
  End   Sub    
       
  Private   Sub   Timer1_Timer()    
  Static   tm   As   Single,   Dlt   As   Single    
  Static   i   As   Integer    
  Static   dtNow   As   Date    
  Static   S   As   String    
  Static   v(1   To   Pub_LoopN)   As   Single    
       
  If   Pub_Timer1Run   Then   Exit   Sub    
  Pub_Timer1Run   =   True    
       
  Call   GetFromMap(strBuffer)    
  If   Left(strBuffer,   1)   =   "   "   Then    
  strBuffer   =   "*"   &   Mid(strBuffer,   2)    
  Call   CopyToMap(strBuffer)    
  Text1.Text   =   strBuffer    
  End   If    
       
  Pub_Timer1Run   =   False    
  End   Sub   'Timer1_Timer    
       
  Module1.bas:与Sampling.vbp之Module1.bas几乎完全相同,只是其中编译常数Sampling=   False。    
  三. 函数描述    
  在Module1.bas中用到几个与文件映射有关的API函数,分述如下:    
  1.CreateFileMapping:创建文件映射对象    
  参数:    
  hFile:Long——欲在其中创建映射的一个已经打开的磁盘文件句柄;    
  LpFileMappingAttributes:Long——通常用0表示使用默认安全对象;    
  FlProtect:Long——打开映射的方式(用API常数表示的读/写或其它);    
  DwMaximumSizeHigh,dwMaximumSizeLow:Long——共同表示文件映射的最大长度(前者为高32位,后者为低32位),通常均设为0表示磁盘文件的实际长度;    
  LpName:   String——指定文件映射对象的名称。    
  返回值:Long——新建文件映射对象的句柄。    
  2.OpenFileMapping:打开一个现成的文件映射对象    
  参数:    
  dwDesiredAccess:Long——用API常数表示的对文件映射的访问方式;    
  bInheritHandle:Long——返回值对与子进程的继承属性,常设为False;    
  lpName:String——准备打开的文件映射对象的名称。    
  返回值:Long——指定的文件映射对象的句柄。    
  3.MapViewOfFile:将一个文件映射对象映射到当前应用程序空间    
  参数:    
  hFileMappingObject:Long——文件映射对象的句柄;    
  dwDesiredAccess:Long——用API常数表示的对文件映射的访问方式;    
  dwFileOffsetHigh,dwFileOffsetLow:Long——共同表示文件中的映射起点(前者为高32位,后者为低32位),通常均设为0表示从文件的起始处开始映射;    
  dwNumberOfBytesToMap:Long——要映射的字节数,通常设为0表示映射整个文件映射对象。    
  返回值:Long——文件映射在内存中的起始地址。    
  4.UnmapViewOfFile:解除当前应用程序中的一个文件映射对象的映射地址空间    
  参数:    
  lpBaseAddress:要解除映射的文件映射起始地址。    
  返回值:Long——非零表示成功,零表示失败。    
  Sampling.vbp的启动窗体Form1.frm在装载时创建一个文件映射(CreateMap),这个创建过程分三步:首先,通过CreateFile,WriteFile,FlushFileBuffers建立一个具有指定长度(LenBuffer   +   1)的磁盘文件DiskFileName;然后,由CreateFileMapping创建一个对应于磁盘文件DiskFileName的文件映射对象MapFileName;最后,用MapViewOfFile将文件映射对象映射到应用程序地址MapAddress。在本例中,磁盘文件建立后便不再与之打交道,以后的操作均针对其映射地址空间。    
  采样通过触发定时器Timer1周期性的进行(采样周期Pub_Period)。每次采样首先通过GetV取得原始样本并放入数组v(本例的样本用随机数替代,实际应用中是从RS232或其他设备取得),然后将其存入映射地址空间以便“管理程序”取用。样本在映射地址空间的存放形式为:“x   采样时间   样本值1   样本值2”。其中x是一个标记,当它为空格时表示新样本,为“*”时表示已取用。   为了方便程序处理,设置了一个样本缓冲strBuffer,由它与映射地址空间交换数据,CopyToMap和GetFromMap也是用于这个目的,CopyToMap(S)是复制S到映射地址空间,而GetFromMap(S)是从映射地址空间取值送到S。    
  在“采样程序”运行过程中,“管理程序”由于某种原因(如维护程序)可能长时间不取用样本(超过一个采样周期),这时,“采样程序”应当把样本存放到另外的磁盘文件,以免丢失样本。考虑到本文主题和文章篇幅,本例未做处理。    
  Manage.vbp启动窗体Form1.frm很简单,仅仅从演示的角度将映射地址空间的数据取出并显示。    
  试验时先运行“采样”,   再运行“管理”,观察两个窗体中的样本数据,我们会发现他们几乎是同步的。感谢文件映射!    
  Top

4 楼BldStu(lyd)回复于 2004-08-04 19:37:13 得分 0

FileHandle   =   CreateFile(DiskFileName,   _  
                                  GENERIC_WRITE   Or   GENERIC_READ,   _  
                                  FILE_SHARE_READ   Or   FILE_SHARE_WRITE,   _  
                                  0,   _  
                                  CREATE_ALWAYS,   _  
                                  FILE_ATTRIBUTE_NORMAL,   _  
                                  0)  
  ----------------------------  
  failTop

5 楼BldStu(lyd)回复于 2004-08-04 20:28:00 得分 0

我修改了DiskFileName和MapFileName后  
  CreateFile成功了,下面的还是不行,  
  呵呵,本人水平有限了:)  
   
  MapHandle   =   OpenFileMapping(FILE_MAP_WRITE,   False,   MapFileName)  
  返回0Top

6 楼Hotthing(豪星)回复于 2004-08-04 20:42:02 得分 0

帮你顶一下!Top

7 楼rainstormmaster(暴风雨 v2.0)回复于 2004-08-04 21:06:31 得分 0

文章写的比较乱,我简单的写了写代码,你参考以下:  
   
  类模块,class1:  
  Option   Explicit  
   
  Const   SECTION_MAP_WRITE   =   &H2  
  Const   SECTION_MAP_READ   =   &H4  
  Const   FILE_MAP_WRITE   =   SECTION_MAP_WRITE  
  Const   FILE_MAP_READ   =   SECTION_MAP_READ  
  Const   PAGE_READONLY   =   &H2  
  Const   PAGE_READWRITE   =   &H4  
  Const   ERROR_ALREADY_EXISTS   =   183&  
  Const   ERROR_INVALID_DATA   =   13&  
   
  Private   Declare   Function   CreateFileMapping   Lib   "KERNEL32"   Alias   "CreateFileMappingA"   _  
                  (ByVal   hFile   As   Long,   lpFileMappigAttributes   As   Any,   _  
                  ByVal   flProtect   As   Long,   ByVal   dwMaximumSizeHigh   As   Long,   ByVal   dwMaximumSizeLow   As   Long,   ByVal   lpName   As   String)   As   Long  
  Private   Declare   Function   MapViewOfFile   Lib   "KERNEL32"   (ByVal   hFileMappingObject   As   Long,   ByVal   dwDesiredAccess   As   Long,   ByVal   dwFileOffsetHigh   As   Long,   ByVal   dwFileOffsetLow   As   Long,   ByVal   dwNumberOfBytesToMap   As   Long)   As   Long  
  Private   Declare   Function   UnmapViewOfFile   Lib   "KERNEL32"   (lpBaseAddress   As   Any)   As   Long  
  Private   Declare   Function   CloseHandle   Lib   "KERNEL32"   (ByVal   hObject   As   Long)   As   Long  
  Private   Declare   Sub   CopyMemory   Lib   "KERNEL32"   Alias   "RtlMoveMemory"   (   _  
        lpvDest   As   Any,   lpvSource   As   Any,   ByVal   cbCopy   As   Long)  
  Private   h   As   Long,   p   As   Long,   e   As   Long  
  Const   MEM_HANDLE   As   Long   =   -1&  
  '产生一个记忆体对应档,名称为sName  
  '该记忆体对应档里面存的资料分成两部份  
  '一个Long值,代表字串的长度,另一为字串,这字串才是要Share部份  
  Function   Create(sName   As   String)   As   Boolean  
          Create   =   False  
          If   sName   =   ""   Then   Exit   Function  
          '   Try   to   create   file   mapping   of   65535   (only   used   pages   matter)  
          h   =   CreateFileMapping(MEM_HANDLE,   ByVal   0,   PAGE_READWRITE,   _  
                                                      0,   65535,   sName)  
          '如果sName原本就存在,则传回的h值是先前Call   CreateFileMapping的handle   of   file   Mapping   Object  
          '而且Err.LastDllError   传回的是ERROR_ALREADY_EXISTS,如果sName原来不存在,则传回新的Handle值  
          '且Err.LastDllError   =   0  
          e   =   Err.LastDllError  
          '   Unknown   error,   bail   out  
          If   h   =   0   Then   Destroy:   Exit   Function  
   
          '   Get   pointer   to   mapping  
          p   =   MapViewOfFile(h,   FILE_MAP_WRITE,   0,   0,   0)  
          If   p   =   0   Then   e   =   Err.LastDllError:   Exit   Function  
          If   e   <>   ERROR_ALREADY_EXISTS   Then  
                  '   Set   size   of   new   file   mapping   to   0   by   copying   first   4   bytes  
                  Dim   c   As   Long   '   =   0  
                  '将0放入记忆体对应档中的前4个Byte  
                  CopyMemory   ByVal   p,   c,   4  
          '   Else  
                  '   Existing   file   mapping  
          End   If  
          e   =   0  
          Create   =   True  
  End   Function  
  Property   Get   Data()   As   String  
          If   h   =   0   Or   p   =   0   Then   e   =   ERROR_INVALID_DATA:   Exit   Property  
          Dim   c   As   Long,   sData   As   String  
          CopyMemory   c,   ByVal   p,   4  
          '   Copy   rest   of   memory   into   string  
          If   c   =   0   Then   Exit   Property   '   Data   =   sEmpty  
          sData   =   String$(c,   0)  
          '将字串放入记忆体对应档中的第4个Byte之後  
          CopyMemory   ByVal   sData,   ByVal   (p   +   4),   c  
          Data   =   sData  
  End   Property  
   
  Property   Let   Data(s   As   String)  
          If   h   =   0   Or   p   =   0   Then   e   =   ERROR_INVALID_DATA:   Exit   Property  
          Dim   c   As   Long  
          c   =   Len(s)  
          '   Copy   length   to   first   4   bytes   and   string   to   remainder  
          CopyMemory   ByVal   p,   c,   4  
          CopyMemory   ByVal   (p   +   4),   ByVal   s,   c  
  End   Property  
   
  Property   Get   LastErr()   As   Long  
          LastErr   =   e  
  End   Property  
  Private   Sub   Destroy()  
        Dim   i   As   Long  
          i   =   UnmapViewOfFile(p)  
          i   =   CloseHandle(h)  
          h   =   0  
          p   =   0  
  End   Sub  
   
  Private   Sub   Class_Terminate()  
          If   h   <>   0   Then   Destroy  
  End   Sub  
   
   
  窗体(一个textbox,两个按钮):  
  Option   Explicit  
  Dim   mtest   As   New   Class1  
  Private   Sub   Command1_Click()  
          mtest.Create   "hello_test"  
          mtest.Data   =   Text1.Text  
  End   Sub  
   
  Private   Sub   Command2_Click()  
          mtest.Create   "hello_test"  
          Text1.Text   =   mtest.Data  
  End   Sub  
   
  Private   Sub   Form_Load()  
          Command1.Caption   =   "Set   Data"  
          Command2.Caption   =   "Get   Data"  
  End   Sub  
   
   
   
  然后分两次编译成两个可执行文件,并进行测试  
   
  Top

8 楼ljc_zy(彷徨)回复于 2004-08-05 09:02:59 得分 0

我没有使用类,成功的实现了通过内存映射文件共享,而且读采用的是  
  OpenFileMapping  
  在MSDN上有个例子,用的是vc,把它改成用vb实现就好了。Top

9 楼derway()回复于 2004-08-05 09:38:09 得分 0

谢谢"暴风雨   v2.0"的指点!!!  
  你写的那一段代码我已经进行编译测试,没有问题,  
  同时你写的那一段代码相比之下也明了很多,并使用了类模块,简化了很多.  
  昨天晚上我花了两个钟对那段贴出的代码分析了一下,  
  发现错误主要出在  
  DiskFileName   =   "D:\Article\Mapping\Sample"    
  MapFileName   =   DiskFileName   &   "Map"    
  这两行里面.他这里   DiskFileName   给出的并不是磁盘文件名,而是一个路径,  
  所在   CreateFile   时不成功;   并且   MapFileName    
  的表示方法也不对,所以在   CreateFileMapping   时也不成功.用不着加路径.  
  采样周期(秒)也多了一个感叹号.  
  然后我修改了一下,也就实现了它的那个效果.  
  虽然它看起来很烦琐,但是核心的代码也就几行.  
  当中也可做一些修改,把它简单化.  
   
  谢谢"暴风雨   v2.0"!!  
  但我不知道的是,你给的那一段代码产生异常的机率有多大?  
  因为你这种生成文件映射对象的方式和我贴的那段程序不同,  
  它是将一个固定的文件生成一个映射对象的.Top

10 楼rainstormmaster(暴风雨 v2.0)回复于 2004-08-05 12:48:04 得分 0

//谢谢"暴风雨   v2.0"!!  
  但我不知道的是,你给的那一段代码产生异常的机率有多大?  
   
  放心的用吧,我这段代码是在内存中建立一个FileMappingTop

11 楼daviddivad(你真行,居然比我还快! Scorpio)回复于 2004-08-05 15:24:59 得分 0

 
  小小建议:  
   
  在属性Data过程中有个小问题:  
  Property   Let   Data(s   As   String)  
          If   h   =   0   Or   p   =   0   Then   e   =   ERROR_INVALID_DATA:   Exit   Property  
          Dim   c   As   Long  
          c   =   Len(s)       //需要修改这行  
          '   Copy   length   to   first   4   bytes   and   string   to   remainder  
          CopyMemory   ByVal   p,   c,   4  
          CopyMemory   ByVal   (p   +   4),   ByVal   s,   c  
  End   Property  
   
  上面注释的那行最好改为  
  c   =   LenB(StrConv(s,vbFromUnicode))  
   
  否则,如果你进程之间通讯的是中文字符或者是中英文混合字符时会出错,字符会被截掉。  
  Top

12 楼rainstormmaster(暴风雨 v2.0)回复于 2004-08-05 15:35:35 得分 0

谢谢daviddivad(你真行,居然比我还快!   Scorpio)的提醒Top

13 楼ljc_zy(彷徨)回复于 2004-08-05 16:59:56 得分 0

厉害,学习,收藏。Top

14 楼doudoushen()回复于 2004-08-10 09:01:05 得分 0

可是中文的不行阿  
  以前看过熊超的     但是他那个太难了     谁能简化点并且能传递中文的代码Top

15 楼rainstormmaster(暴风雨 v2.0)回复于 2004-08-10 09:25:03 得分 0

//可是中文的不行阿  
   
  你先给类模块添加声明:  
  Private   Declare   Function   lstrlen   Lib   "kernel32"   Alias   "lstrlenA"   (ByVal   lpString   As   String)   As   Long  
   
  再把Let   Data换成下面的:  
  Property   Let   Data(s   As   String)  
          If   h   =   0   Or   p   =   0   Then   e   =   ERROR_INVALID_DATA:   Exit   Property  
          Dim   c   As   Long  
          c   =   lstrlen(s   +   Chr(0))  
          '   Copy   length   to   first   4   bytes   and   string   to   remainder  
          CopyMemory   ByVal   p,   c,   4  
          CopyMemory   ByVal   (p   +   4),   ByVal   s,   c  
  End   Property  
   
  这样,应该就可以了Top

16 楼bafenghan(我爱睡觉我爱睡觉我爱睡觉我真的好爱睡觉)回复于 2005-08-26 09:58:37 得分 0

关注   啊   !Top

17 楼chendjin(蹭分来了)回复于 2005-08-26 10:28:58 得分 0

强,学习,收藏。Top

相关问题

  • 再论在VB中显示XML数据
  • 用文件映射共享进程数据的问题
  • 再论在VB中显示XML数据 (高分相送)
  • ===用VB如何杀进程===
  • 映射
  • 怎样利用dll在进程间共享变量(不使用内存映射文件)
  • 再论i++.
  • 再论vtpr
  • 再论乱码。
  • vb中如何杀死一个进程?

关键词

  • 映射
  • 文件
  • 样本
  • 代码
  • vb
  • 内存
  • 应用程序
  • 数据
  • 采样
  • 磁盘

得分解答快速导航

  • 帖主:derway

相关链接

  • Visual Basic类图书
  • Visual Basic类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo