| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 663 人关注过本帖
标题:延续先前的问题~因为结构体会增长~要如何在循环中使用CopyMemory?
只看楼主 加入收藏
wube
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:23
帖 子:1820
专家分:3681
注 册:2011-3-24
结帖率:97.66%
收藏
已结贴  问题点数:40 回复次数:7 
延续先前的问题~因为结构体会增长~要如何在循环中使用CopyMemory?
这次我贴上我的完整结构~我尝试写在循环外或内~只要使用过CopyMemory~之后结构体内容如果有变动~整个VB都会被关闭~这问题请高手协助~或经验分享一下要怎做会比较好~因为被分析的资料~量都是以GB计算的~所以不可能全解析完成再用CopyMemory~

感觉好像是什么释放的动作没做~导致程序死当~事实上每次处理完一个Flow我会ReDim一次~不然到100左右内存会爆掉~

想让每次处理完一个Flow()~新增一个Flow()前~就回传一次~

Form1
程序代码:
Option Explicit

Dim QQQ As New Class1

Private Sub Form_Load()
    Call AAA
End Sub

Private Sub AAA()
    QQQ.Run
    MsgBox WWW.Device_Name
End Sub


Module1
程序代码:
Option Explicit

Public Enum ICMmode
    None = 0
    CP = 1
    FT = 2
End Enum

Public Type MeasuredValue
    MValue                  As String           'Pin脚量测值
    MUnit                   As String           'Pin脚量测单位
End Type

Public Type PinContent
    PinName                 As String           'Pin脚名称
    PinForce                As MeasuredValue    'Force值
    PinForcerng             As MeasuredValue    'ForceRange值
    PinMin                  As MeasuredValue    'Min值
    PinMax                  As MeasuredValue    'Max值
    PinMeas                 As MeasuredValue    'Meas值
    PinMeasrng              As MeasuredValue    'MeasRange值
    PinResult               As String           'Pass or Fail

    SearchedStart           As String           'TMU值

    Windows                 As MeasuredValue    'Windows值
    ResultValue             As MeasuredValue    'Result.Value值

    PattenName              As String           'Function Patten名称
    PattenNumber            As String           'Function Patten编号
    Start                   As String           'Function Start值
    End                     As String           'Function End值
    Size                    As String           'Function Size值

    VRang                   As MeasuredValue    'DPS值
    IRang                   As MeasuredValue    'DPS值
    ClampH                  As MeasuredValue    'DPS值
    ClampL                  As MeasuredValue    'DPS值
End Type

Public Type Pin
    PinData()               As PinContent       'Pin脚测试资料
    PinNum                  As Integer          'Pin脚总数
    ItemResult()            As String           'Pass or Fail
End Type

Public Type Bin
    SoftBin                 As Integer          'Software Bin Number
    HwardBin                As Integer          'Hardward Bin Number
End Type

Public Type Site
    SiteData()              As Pin              '该SiteNum中的资料
    SiteNum                 As Integer          'Site数量
    SiteCount               As Integer          'Site数量计算
    ItemType                As String           'ItemTest类型
    ItemTestTime            As String           'ItemTest时间 + 日期
    SiteBin()               As Bin              'SiteBin编号
    ItemTestName            As String           'ItemTest名称
End Type

Public Type ItemTest
    ItemTestData()          As Site             '该ItemTest中的资料
    ItemTestNumber          As Integer          '该SubTest中ItemTest总数
    SubTestName             As String           '该ItemTest所属SubTest名称
    SubTest_ID              As String           '该SubTest ID编号
    SubTest_FailBin         As String           '该SubTest Fail Bin Number
End Type

Public Type Coordinate
    X                       As Integer          'X座标
    Y                       As Integer          'Y座标
End Type

Public Type SubTest
    SubTestData()           As ItemTest         '该SubTest中的资料
    SubTestNumber           As Integer          '该Flow中SubTest总数
    FlowTestTime            As String           '该Flow测试时间 + 日期
    FlowTestCoordinate      As Coordinate       '工程模式下的测试座标
    Test_Dut_Count          As Integer          '该Flow中Dut数
End Type

Public Type CPMode
    Data_Log_Vesion         As String           'Data Log Vesion
    Lot_ID                  As String           'Lot ID(CP)
    Wafer_ID                As String           'Wafer ID(CP)
    Prober_Temperature      As String           'Prober Temperature(CP)
    Probe_card_number       As String           'Probe Card Number(CP)
End Type

Public Type FTMode
    Customer_Lot_ID         As String           'Customer Lot ID(FT)
    Internal_Lot_ID         As String           'Internal Lot ID(FT)
    Dut_Board               As String           'Dut Board(FT)
End Type

Public Type Flow
    FlowData()              As SubTest          '该Flow中的资料
    FlowNumber              As Integer          '该Log档中Flow的总数

    MCP                     As CPMode           'IC种类(CP)
    MFT                     As FTMode           'IC种类(FT)

    LogFileName             As String           'Log档所在路径位置
    StartTestTime           As String           '该Log档的测试时间 + 日期
    PC_Name                 As String           'PC Name
    IP_Address              As String           'IP Address
    EndTestTime             As String           '该Log档的结束测试时间 + 日期
    Project_Path            As String           'Project Path
    Test_DUTs               As String           'Test DUTs
    Test_Mode               As String           '工程模式或是量产模式
    Flow_Name               As String           '该Log档的Flow名称
    Device_Name             As String           'Device Name
    Device_Pin_Count        As String           '测试Pin脚总数
End Type

Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef Destination As Flow, ByRef Source As Flow, ByVal Length As Long)

Public WWW As Flow


Class1
程序代码:
Option Explicit

Private ABC As Flow

Public Sub Run()
    Call Assign
End Sub

Private Function Assign() As Boolean
Dim i As Integer

    For i = 0 To 5
        ABC.FlowNumber = i
        ReDim ABC.FlowData(ABC.FlowNumber)
        ABC.FlowData(ABC.FlowNumber).SubTestNumber = 123
        ABC.Device_Name = "123"
    Next i
    
    CopyMemory WWW, ABC, CInt(LenB(ABC))    '问题会从这行之后开始产生~
    
    For i = 6 To 10
        ABC.FlowNumber = i
        ReDim ABC.FlowData(ABC.FlowNumber)
        ABC.FlowData(ABC.FlowNumber).SubTestNumber = 123
        ABC.Device_Name = "123"
    Next i
    
End Function
搜索更多相关主题的帖子: 结构体 
2011-05-05 23:32
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4943
专家分:30067
注 册:2008-10-15
收藏
得分:0 
结构体内,有 变长字符时,好像使用 CopyMemory 就会 造成 访问内存失败而导致 程序 或者 VB6 被自动关闭。

我记得是这样的,没去测试过。你自己写个简单的程序测试一下是不是这个问题。





授人于鱼,不如授人于渔
早已停用QQ了
2011-05-06 08:03
jiashie
Rank: 8Rank: 8
等 级:贵宾
威 望:10
帖 子:237
专家分:999
注 册:2009-4-30
收藏
得分:15 
也许你走错路了,其实根本不需要用到copymemory。
1、两个相同(或相容)的结构体之间的赋值,可以用LSet
2、内部类模块中需要传递自定义结构体作参数时,可以用friend sub/function
程序代码:
'module 
Option Explicit

Public Type MyType
    id As Long
    value As String
    extra As String
End Type

Public g_t As MyType

程序代码:
'class
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSrc As Any, ByVal ByteLen As Long)

Private m_t As MyType

Public Function SetType(ByVal lpMyType As Long) As Long
    CopyMemory m_t, ByVal lpMyType, LenB(m_t)
    Debug.Print m_t.id, m_t.value, m_t.extra
End Function

Friend Function SetTypeEx(ByRef t As MyType) As Long
    LSet m_t = t
    Debug.Print m_t.id, m_t.value, m_t.extra
End Function

Public Function Assign() As Long
    m_t.id = 3
    m_t.value = "ddddd"
    m_t.extra = "eeeee"
    LSet g_t = m_t
End Function
2011-05-06 09:41
jiashie
Rank: 8Rank: 8
等 级:贵宾
威 望:10
帖 子:237
专家分:999
注 册:2009-4-30
收藏
得分:15 
Ps.好像两个相同结构体之间赋值,直接用=就可以了。
我高估了Lset拷贝结构体的能力了,好像只能是相同的类型,而不是“相容”

[ 本帖最后由 jiashie 于 2011-5-6 09:52 编辑 ]
2011-05-06 09:46
wube
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:23
帖 子:1820
专家分:3681
注 册:2011-3-24
收藏
得分:0 
以下是引用风吹过b在2011-5-6 08:03:05的发言:

结构体内,有 变长字符时,好像使用 CopyMemory 就会 造成 访问内存失败而导致 程序 或者 VB6 被自动关闭。

我记得是这样的,没去测试过。你自己写个简单的程序测试一下是不是这个问题。

我上面那段代码的结果和你推测的是一样~我试过了想不通才上来问~

不要選我當版主
2011-05-06 11:19
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4943
专家分:30067
注 册:2008-10-15
收藏
得分:10 
VB规定,定长字符串,
就类似于 固定的数组  dim s as string*10     dim s(1 to 10) as byte 相当。

变长字符串,VB内部使用 指针来操作。(C语言的定义)
dim s as string   
这时,S 里,保存的是一个地址,然后这个地址 所指向的一个内存地址,则保存着字符串的实际内容。

CopyMemory  ,复制内存数据,必须在相同大小的内存之间进行。
当为定长字符串时,复制内存数据,数据长度是固定的,在定义时就固定好了的,不会出现超长的情况。
当为变长字符串时,复制内存数据,数据内容是 4 个字节(32位地址时),数据长度,你取到的是 字符串长度,写入位置的数据长度是 4字节
而你要把字符串长度的数据复制进去,内存访问超界,写超了。这时,WINDOWS就会自动将此程序关闭,因为执行了非法操作,非法访问内存。

所以,你要复制内存时,必须保存结构体的长度是一样的,如果不一样,写入的长度要比读取的长度要小。
      结果体内,一定不能有 变长字符串。你可以使用 一个大长度的 定长字符串来。虽然会导致内存浪费。

--------------------------
我记得是这样的。

授人于鱼,不如授人于渔
早已停用QQ了
2011-05-06 15:23
wube
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:23
帖 子:1820
专家分:3681
注 册:2011-3-24
收藏
得分:0 
小弟是偷懒没去查MSDN的定义~只是光从使用后的心得来想像~说白话些觉得CopyMemory就好像是先告诉大家有一个人~
然后再到Class中去定义这个人的姓名为路人甲年龄. ...等等资料~定义完毕后~再到别的地方告诉另一个人说路人甲的
小名是小甲~这样日后只要有人叫小甲~那大家都会知道小甲就是路人甲~当然小甲和路人甲都必须是个人~

P.S 最近有个CASE卡很紧~主管天天夺命连环Call~我要赶紧搞定在来弄这些~帖子先让我放个几天再来试吧~

不要選我當版主
2011-05-06 15:38
wube
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:23
帖 子:1820
专家分:3681
注 册:2011-3-24
收藏
得分:0 
跟某高阶且资深的长官询问过了~它也是说用等于就行了~就如同jiashie兄说的一样~用 = 就行了~但是前提是~两个变量都要相同型态~并且结构体必须在模块中做Public声明~

而若一开始坚持一定要将结构写在CLASS做也可以~那也是要像jiashie兄说的~
1.先搞出个Type Library的DLL档再去用VB载入~这样VB承认是公用结构后才会让你使用~
2.否则只能像很多API一样~用了一些莫名奇妙的结构当引数型态~让使用者要用的时候~还要另外特别帮它做声明才行~常见的 Rect 或 BrowseInfo 都是要自己查~

但是新问题来了~这可能对你们这些老手来说比较简单~要如何在Class之中新增一个事件~当每次Count+1的时候~将程序执行控制权转交给Form?

(Form跟模块间我知道~类跟控件间~版主先前有给个类钩子工程可以参考着用~但是Form和类之间我又一头雾水了~应该不会又是差个等于吧...)

P.S 我隔壁较低阶的长官也提起兴趣帮我试了一下~Copymemory的第三个引数~是源自于结构体内各成员型态的预设大小~例如定义一个字符串成员~长度就是4字节~7个就是28Bytes~
所以和我预想的为ByRef有些差距~也或者是我自行去变更的API的ByVal宣告的原因吧~以我上面那种结构体来说~是无法预期结构长度~所以他的结论是不适合用Copymemory的API来做这~

[ 本帖最后由 wube 于 2011-5-7 03:34 编辑 ]

不要選我當版主
2011-05-07 03:22
快速回复:延续先前的问题~因为结构体会增长~要如何在循环中使用CopyMemory?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.020839 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved