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

解决方案 »

  1.   

    在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 
      

  2.   

    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 
      

  3.   

    #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很简单,仅仅从演示的角度将映射地址空间的数据取出并显示。 
    试验时先运行“采样”, 再运行“管理”,观察两个窗体中的样本数据,我们会发现他们几乎是同步的。感谢文件映射! 
      

  4.   

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

  5.   

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

  6.   

    文章写的比较乱,我简单的写了写代码,你参考以下:类模块,class1:
    Option ExplicitConst 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 PropertyProperty 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 PropertyProperty 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 SubPrivate 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 SubPrivate Sub Command2_Click()
        mtest.Create "hello_test"
        Text1.Text = mtest.Data
    End SubPrivate Sub Form_Load()
        Command1.Caption = "Set Data"
        Command2.Caption = "Get Data"
    End Sub然后分两次编译成两个可执行文件,并进行测试
      

  7.   

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

  8.   

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

  9.   

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

  10.   


    小小建议:在属性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))否则,如果你进程之间通讯的是中文字符或者是中英文混合字符时会出错,字符会被截掉。
      

  11.   

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

  12.   

    //可是中文的不行阿你先给类模块添加声明:
    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这样,应该就可以了