你无法确定你的CueAD在内存中是连成一片的
XAD也同样

LSet XAD(0) = CurAD(0)
即可

解决方案 »

  1.   

    结构体中的string可能会导致一些问题。他们是可变长度的,改为string *100这类的定义试试。
    另外,我认为CurAD在内存中应该是连成一片的,因为定义是数组,内存必须连续。
      

  2.   

    好,两位回答不错,回头会有分的。我的应用是将整个CurAD通过网卡传到另一台机子,而且每秒传2回,所以只能拷贝内存,对此,nothingneed(玄痴)您是否有更好的办法呢?分数加到 300分!
      

  3.   

    我觉得如果您是通过网卡传的话
    瓶颈不一定在拷贝这里
    还有可以试试NowCan的方法,作定长string
    NowCan:
    我只能验证在c++中数组是连续存储的,(对C++结构体是否连续存储至今存疑)
    没有方法验证在VB中也是同样,也没有看到相关书籍的介绍
    如果您有在VB中验证的方法请多指教
      

  4.   

    有个朋友给出馊主意:
    Call CopyMemory(ByVal XAD(0), dd(0), alen)
    你试试,不过后面会死机,呵呵呵:)还真是。
      

  5.   

    我觉得nothingneed(玄痴)说的比较有道理,我将结构里的STRING类型和自定义类型的变量都注释,结果运行还是死了,真是莫名其妙。
      

  6.   

    将窗体代码修改如下,运行,好象没有问题,特请nothingneed(玄痴)等众高手点评:
    Option ExplicitPrivate Sub Command1_Click()
        Dim i%
        Dim eLen As Integer
        Dim aLen As Long
        Dim dd() As Byte
        Dim XAD(0 To 71) As PType
        
        For i = 0 To 71
            CurAD(i).Name = i & "参数"
        Next i
        aLen = 0
        'For i = 0 To 71
        '    aLen = aLen + LenB(CurAD(i))
        '    LSet XAD(i) = CurAD(i)
        'Next i
        'eLen = LenB(CurAD(0))
        'aLen = eLen * (UBound(CurAD) - LBound(CurAD) + 1)
        'ReDim dd(0 To aLen - 1)
        For i = 0 To 71
            eLen = LenB(CurAD(i))
            ReDim dd(0 To eLen - 1)
            Call CopyMemory(dd(0), CurAD(i), eLen)
            Call CopyMemory(XAD(i), dd(0), eLen)
        Next i
        For i = 0 To 71
            Debug.Print CurAD(i).Name, XAD(i).Name
        Next i
    End Sub
      

  7.   

    将窗体代码修改如下,运行,好象没有问题,特请nothingneed(玄痴)等众高手点评:
    Option ExplicitPrivate Sub Command1_Click()
        Dim i%
        Dim eLen As Integer
        Dim aLen As Long
        Dim dd() As Byte
        Dim XAD(0 To 71) As PType
        
        For i = 0 To 71
            CurAD(i).Name = i & "参数"
        Next i
        For i = 0 To 71
            eLen = LenB(CurAD(i))
            ReDim dd(0 To eLen - 1)
            Call CopyMemory(dd(0), CurAD(i), eLen)
            Call CopyMemory(XAD(i), dd(0), eLen)
        Next i
        For i = 0 To 71
            Debug.Print CurAD(i).Name, XAD(i).Name
        Next i
    End Sub
      

  8.   

    更正,运行还是有问题,运行后的第一次CALL Command1_Click和第二次CALL Command1_Click将得到不一样的结果,如下:
    第一次调用Command1_Click将在DEBUG窗口显示如下:
    0参数                  
    1参数                  
    2参数                  
    3参数                  
    4参数                  
    5参数                  
    6参数                  
    7参数                  
    8参数                  
    9参数                  
    10参数                
    11参数                
    12参数                
    13参数                
    14参数                
    15参数                
    16参数                
    17参数                
    18参数                
    19参数                
    20参数                
    21参数                
    22参数                
    23参数                
    24参数                
    25参数                
    26参数                
    27参数                
    28参数                
    29参数                
    30参数                
    31参数                
    32参数                
    33参数                
    34参数                
    35参数                
    36参数                
    37参数                
    38参数                
    39参数                
    40参数                
    41参数                
    42参数                
    43参数                
    44参数                
    45参数                
    46参数                
    47参数                
    48参数                
    49参数                
    50参数                
    51参数                
    52参数                
    53参数                
    54参数                
    55参数                
    56参数                
    57参数                
    58参数                
    59参数                
    60参数                
    61参数                
    62参数                
    63参数                
    64参数                
    65参数                
    66参数                
    67参数                
    68参数                
    69参数                
    70参数                
    71参数                第二次调用Command1_Click将在DEBUG窗口显示如下:0参数         0参数
    1参数         1参数
    2参数         2参数
    3参数         3参数
    4参数         4参数
    5参数         5参数
    6参数         6参数
    7参数         7参数
    8参数         8参数
    9参数         9参数
    10参数        10参数
    11参数        11参数
    12参数        12参数
    13参数        13参数
    14参数        14参数
    15参数        15参数
    16参数        16参数
    17参数        17参数
    18参数        18参数
    19参数        19参数
    20参数        20参数
    21参数        21参数
    22参数        22参数
    23参数        23参数
    24参数        24参数
    25参数        25参数
    26参数        26参数
    27参数        27参数
    28参数        28参数
    29参数        29参数
    30参数        30参数
    31参数        31参数
    32参数        32参数
    33参数        33参数
    34参数        34参数
    35参数        35参数
    36参数        36参数
    37参数        37参数
    38参数        38参数
    39参数        39参数
    40参数        40参数
    41参数        41参数
    42参数        42参数
    43参数        43参数
    44参数        44参数
    45参数        45参数
    46参数        46参数
    47参数        47参数
    48参数        48参数
    49参数        49参数
    50参数        50参数
    51参数        51参数
    52参数        52参数
    53参数        53参数
    54参数        54参数
    55参数        55参数
    56参数        56参数
    57参数        57参数
    58参数        58参数
    59参数        59参数
    60参数        60参数
    61参数        61参数
    62参数        62参数
    63参数        63参数
    64参数        64参数
    65参数        65参数
    66参数        66参数
    67参数        67参数
    68参数        68参数
    69参数        69参数
    70参数        70参数
    71参数        71参数
      

  9.   

    谢谢 prefix 老弟。300分给你,如果以后有机会见面,请你一顿。
    nothingneed(玄痴)、NowCan(能量、激情、雨水、彩虹——雷雨云)、fraser01(wang) ,我另开帖子给你们分:http://www.csdn.net/expert/topic/371/371130.shtm
    你的答案我公布如下,相信你也不会介意吧。——————————————————————————
    '模块代码:
    Option ExplicitType SetType '操作工工艺给定
        Value As Single                             '给定值
        Time As Date                                '给定值起始时间
    End Type
    Type PType 'AD采集参数类型
        Index As Integer                            '参数编号
        '/////////////////////////////////////////////////////////////////////////////////////
        '// String 类型的变量在自定义类型中如果要对整个类型进行内存拷贝,应该使用定长
        '// 虽然由于VB本身进行了一些附加工作,未必总是都会出错,
        '// 但考虑到变量在内存中的地址与大小的问题,仍不应该使用变长String
        '//
        Name As String * 30                          '参数名称
        Unit As String * 30                           '量纲
        SndIndex As String * 30                       '语音报警ID编号串
        
        SndEnabled As Boolean                       '是否允许语音报警
        
        ListFmt As String * 30                        '指定列表格式
        '/////////////////////////////////////////////////////////////////////////////////////
        SetCyc As Date                              '操作给定周期
        SetCycBeginTime As Date                     '操作给定周期起始时间
        SetCount As Integer                         '操作给定个数
        SetVal() As SetType                         '操作工工艺给定
        ADDevice As Integer                         'AD板编号
        ADChanel As Integer                         '此参数采集通道
        Max As Single                               '最大量限
        Min As Single                               '最低量限
        HHlimit As Single                           '极高报警
        Hlimit As Single                            '高报警
        Llimit As Single                            '低报警
        LLlimit As Single                           '极低报警
        Quotiety As Single                          '斜率系数,放大系数
        Damp As Single                              '阻尼
        Equalize As Single                          '补偿值
        Excursion As Single                         '漂移
        B_HHlimit As Integer                           '极高报警(先前的,用于工艺曲线的描绘)
        B_Hlimit As Integer                            '高报警
        B_Llimit As Integer                            '低报警
        B_LLlimit As Integer                           '极低报警
        B_Quotiety As Integer                          '斜率系数,放大系数
        B_Damp As Integer                              '阻尼
        B_Equalize As Integer                          '补偿值
        B_Excursion As Integer                         '漂移
        Value As Single                             '当前值
        TmpSum As Single                            '过程变量,用于对当前值的累加求平均
        AlarmStatus As Integer                      '当前报警在状态
        PreAlarm As Integer                         '前一报警值(标志):-2  -1  0  1  2
        PreVal As Single                            '采集前值
        PreAD As Single                             '采集前AD值
    End TypePublic Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)Public CurAD(0 To 71) As PType                         'AD采集的参数'窗体代码,包含一个COMMAND控件
    Option ExplicitPrivate Sub Command1_Click()
        Dim i%
        Dim eLen As Integer
        Dim alen As Long
        Dim dd() As Byte
        Dim XAD(0 To 71) As PType
        
        For i = 0 To 71
            CurAD(i).Name = i & "参数"
        Next i
        
        eLen = LenB(CurAD(0))
        alen = eLen * (UBound(CurAD) - LBound(CurAD))
        ReDim dd(0 To alen - 1)
        
        ' CopyMemory 使用有误,因为CopyMemory 的声明中是按引用(ByRef)传递,因此实际传给
        ' CopyMemory 所使用的值是 dd(0) 的引用的地址,对API来说,是不能对一个引用的地址进行操作的
        
        ' 实际上与该两句相关的操作可简化成...
        'Call CopyMemory(dd(0), CurAD(0), alen)
        'Call CopyMemory(XAD(0), dd(0), alen)
        ' 这一句:
        Call CopyMemory(ByVal XAD(0), ByVal CurAD(0), LenB(XAD(0)) * (UBound(XAD) + 1))  '使用 ByVal
        
        '//////////////////////////////
        For i = 0 To 71
            Debug.Print CurAD(i).Name, XAD(i).Name
        Next i
    End Sub____________________________________
    结帖。