CopyMemory는 지정한 메모리의 한 장소에서 지정한 메모리의 한 장소에 지정한 바이트 만큼을 복사한다.
CopyMemory는 RtlMoveMemory 함수를 호출하여 사용한다

메모리의 지정된 부분을 복사한다.
사용시 Type 데이타형 복사시에 Type데이타를 직접 사용하여도 된다, copymemory a,b,lenb(b)

● 선언
Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSource As Any, ByVal dwLength As Long)
Sub RtlMoveMemory Lib "kernel32" (hpvDest As Any, ByVal hpvSource As Long, ByVal cbCopy As Long)

● 인수

Destination ━ 복사받을 변수, 복사받을 메모리 위치가 기억된 주소 
Source ━ 복사할 변수, 복사할 멤모리 위치가 기억된 주소
Length ━ 복사할 바이트 수

VB의 배열은 SafeArray를 사용한다.
VB의 배열은 구조는
우선 배열은 SafeArray 구조를 가키리키는 메모리를 가리킨다(이것이 포인터)
즉 배열은 SafeArray 구조를 가리키는 포인터에 포인터가 된다.

다음 소스를 보면 VB에서의 배열의 구조와, SafeArray구조를 알수 있다.

다음은 소스의 초기 이미지이다.


초기 이미지에서 배열 내용 표시는 배열에 저장된 내용을 표시하는 것이고
배열 정보 표시 버튼은 배열 정보 즉 SafeArray구조를 메모리에서 복사하여 얻은 정보를 표시한다


다음은 소스이다
' VB에서 배열은 SafeArray이다.
' 배열->SafeArray 가리키는 포인터->SafeArray 구조->실제 데이타
Option Explicit ' 모든 변수는 선언된 뒤에 사용할 수 있다.

Private Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" (Var() As Any) As Long ' 배열의 주소를 얻는다
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal length As Long) ' 메모리 복사

Private TestTable(5, 10) As Long

Private Type SAFEARRAYBOUND
    cElements As Long ' 차원 요소 갯수
    lLbound As Long ' ' 차원 하한값
End Type

Private Type SAFEARRAY
    cDims As Integer ' 테이블의 차원수
    fFeatures As Integer ' 배열 특징,자료형인지, 가변인지, 등
    cbElements As Long ' 배열의 요소의 크기는
    cLocks As Long ' 럭 카운터
    pvData As Long ' 배열의 실제 데이타 시작 위치
    rgsabound(1 To 2) As SAFEARRAYBOUND ' 각 배열 차원의 한계 정보
End Type

Private Sub Command1_Click() ' 테이블 표시
    Dim Row As Long
    Dim Col As Long

    Text1.Text = vbNullString
    For Row = 0 To UBound(TestTable, 1)
        For Col = 0 To UBound(TestTable, 2)
            Text1.Text = Text1.Text & Format(TestTable(Row, Col), "@@@")
        Next Col
        Text1.Text = Text1.Text & vbCrLf
    Next Row
End Sub

Private Sub Command2_Click() ' 테이블 정보 표시
    Dim Safe As SAFEARRAY
    Dim PointerArray As Long
    Dim PointerSafeArray As Long

    Text1.Text = ""
    PointerArray = VarPtrArray(TestTable) ' 배열 시작 주소를 얻는다.
    Text1.Text = Text1.Text & "배열의 시작 주소: " & Hex(PointerArray) & vbCrLf
    CopyMemory PointerSafeArray, ByVal PointerArray, Len(PointerSafeArray)
    Text1.Text = Text1.Text & "SafeArray 포인터 주소: " & Hex(PointerSafeArray) & vbCrLf
    CopyMemory Safe, ByVal PointerSafeArray, Len(Safe)
    Text1.Text = Text1.Text & "배열의 차원은: " & Safe.cDims & vbCrLf
    Text1.Text = Text1.Text & "배열의 특징은: " & Hex(Safe.fFeatures) & vbCrLf
    Text1.Text = Text1.Text & "배열 요소의 크기는: " & Hex(Safe.cbElements) & vbCrLf
    Text1.Text = Text1.Text & "배열 럭 카운터: " & Hex(Safe.cLocks) & vbCrLf
    Text1.Text = Text1.Text & "배열의 실제 데이타 위치는: " & Hex(Safe.pvData) & vbCrLf
    Text1.Text = Text1.Text & "첫번재 요수 주소: " & Hex(VarPtr(TestTable(0, 0))) & vbCrLf
    Text1.Text = Text1.Text & "첫번째 차원 요소 갯수: " & Safe.rgsabound(1).cElements & vbCrLf
    Text1.Text = Text1.Text & "첫번째 차원 요소 하한값: " & Safe.rgsabound(1).lLbound & vbCrLf
    Text1.Text = Text1.Text & "두번째 차원 요소 갯수: " & Safe.rgsabound(2).cElements & vbCrLf
    Text1.Text = Text1.Text & "두번째 차원 요소 하한값: " & Safe.rgsabound(2).lLbound & vbCrLf
End Sub

Private Sub Form_Load()
    Dim Row As Long
    Dim Col As Long

    For Row = 0 To UBound(TestTable, 1)
        For Col = 0 To UBound(TestTable, 2)
            TestTable(Row, Col) = Row * (UBound(TestTable, 2) + 1) + Col + 1
        Next Col
    Next Row
End Sub

+ Recent posts