To register for an Internet.com membership to receive newsletters and white papers, use the Register button ABOVE.
To participate in the message forums BELOW, click here
VBForums  

VB Wire News
Part 10 of the Visual Basic .NET 2010 Express Tutorial Complete!
How to Use the Visual Studio Code Analysis Tool FxCop
Article :: Interview with Andrei Alexandrescu (Part 3 of 3)
Introducing Visual Studio LightSwitch
Visual Studio LightSwitch Beta 1 is Available



Go Back   VBForums > Visual Basic > API

Reply Post New Thread
 
Thread Tools Display Modes
Old Jan 14th, 2006, 09:48 AM   #1
BLUE_SEA
Member
 
Join Date: Dec 05
Posts: 43
BLUE_SEA is an unknown quantity at this point (<10)
What's all the fuss about COPYMEMORY ?

Hi there,

Can anybody show a practical real-world use for the CopyMemory API in VB apart from simply copying memory bits to an array ?

I still don't really understand all the fuss about this function .

Thanks in advance.
BLUE_SEA is offline   Reply With Quote
Old Jan 15th, 2006, 10:22 AM   #2
moeur
Old Member
 
moeur's Avatar
 
Join Date: Nov 04
Location: In Hiding.... Weather: sizzzzlin'........ Code: Secret
Posts: 2,701
moeur is a glorious beacon of light (400+)moeur is a glorious beacon of light (400+)moeur is a glorious beacon of light (400+)moeur is a glorious beacon of light (400+)moeur is a glorious beacon of light (400+)
Re: What's all the fuss about COPYMEMORY ?

where is the fuss besides here?
moeur is offline   Reply With Quote
Old Jan 15th, 2006, 10:32 AM   #3
crptcblade
The Devil
 
crptcblade's Avatar
 
Join Date: Aug 00
Location: Quetzalshacatenango
Posts: 9,091
crptcblade is a jewel in the rough (200+)crptcblade is a jewel in the rough (200+)crptcblade is a jewel in the rough (200+)
Re: What's all the fuss about COPYMEMORY ?

You use CopyMemory to convert a pointer into a UDT for many APIs.
__________________
Laugh, and the world laughs with you. Cry, and you just water down your vodka.


Take credit, not responsibility
crptcblade is offline   Reply With Quote
Old Mar 20th, 2006, 09:24 PM   #4
VBAhack
Fanatic Member
 
VBAhack's Avatar
 
Join Date: Dec 04
Location: Sector 000
Posts: 556
VBAhack will become famous soon enough (65+)
Re: What's all the fuss about COPYMEMORY ?

CopyMemory is used to create basic structures such as stacks, queues, and linked lists.
VBAhack is offline   Reply With Quote
Old Mar 22nd, 2006, 04:56 AM   #5
yrwyddfa
Frenzied Member
 
yrwyddfa's Avatar
 
Join Date: Aug 01
Location: England
Posts: 1,237
yrwyddfa will become famous soon enough (65+)
Re: What's all the fuss about COPYMEMORY ?

VB, generally, does not allow direct access to memory. This can be prohibitively slow - in some cases - so some programmers prefer to get dirty and get down to the details to provide a (sometimes) huge increase in performance.

In many cases CopyMemory is used to dereference a pointer (as described above) but this is mostly unecessary.

For instance you can use IDL (to create a typelibrary) and squeeze implied semantic functionality from a few other 'unknown' functions:

VB Code:
  1. [dllname("msvbvm60.dll")]
  2.     module VirtualMachine
  3.     {
  4.         [entry("GetMem4"),propget]
  5.         HRESULT MemLong ([in] long Address,[out,retval]long* Value);
  6.         [entry("PutMem4"),propput]
  7.         HRESULT MemLong ([in] long Address,[in] long Value);
  8.     }

This allows the following:

VB Code:
  1. Dim lp As Long
  2.     Dim l As Long
  3.    
  4.     l = MemLong(lp)
  5.     MemLong(lp) = l

. . . which allows for more natural dereferencing code (and it's much MUCH) faster.

I think that CopyMemory is so popular is because it's simply that it's so well known.
__________________
"As far as the laws of mathematics refer to reality, they are not certain; and as far as they are certain, they do not refer to reality." - Albert Einstein

It's turtles! And it's all the way down


Thoughts

Last edited by yrwyddfa; Mar 22nd, 2006 at 05:12 AM.
yrwyddfa is offline   Reply With Quote
Old Mar 22nd, 2006, 05:10 AM   #6
yrwyddfa
Frenzied Member
 
yrwyddfa's Avatar
 
Join Date: Aug 01
Location: England
Posts: 1,237
yrwyddfa will become famous soon enough (65+)
Re: What's all the fuss about COPYMEMORY ?

For instance, consider the following VB code (it won't run - if you want to play I can provide a link to the project)

VB Code:
  1. Option Explicit
  2. 'Public Type MATRIX_HEADER
  3. '    i As Long               'Offset:0
  4. '    j As Long               'Offset:4
  5. '    Size As Long            'Offset:8
  6. '    hHeap As Long           'Offset:12
  7. 'End Type
  8. Public Function MCreate(i As Long, j As Long) As Long
  9.     On Error GoTo ERR_MCreate
  10.     Dim HeaderSize As Long
  11.     Dim pHeap As Long
  12.     Dim hHeap As Long
  13.     Dim Size As Long
  14.    
  15.     '******************************
  16.     '* Get the required sizes . . .
  17.     '******************************
  18.     Size = i * j * 4
  19.     '**********************
  20.     '* Get the memory . . .
  21.     '**********************
  22.     hHeap = HeapCreate(HEAP_GENERATE_EXCEPTIONS, 16 + Size, 0)
  23.     pHeap = HeapAlloc(hHeap, HEAP_GENERATE_EXCEPTIONS, Size)
  24.    
  25.     '********************************
  26.     '* Write the header records . . .
  27.     '********************************
  28.     MemLong(pHeap) = i
  29.     MemLong(pHeap + 4) = j
  30.     MemLong(pHeap + 8) = Size
  31.     MemLong(pHeap + 12) = hHeap
  32.    
  33.     '********************************************
  34.     '* Return pointer to start of structure . . .
  35.     '********************************************
  36.     MCreate = pHeap
  37.    
  38.     Exit Function
  39.    
  40. ERR_MCreate:
  41.     Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext
  42. End Function
  43. Public Sub MDestroy(pMatrix As Long)
  44.     On Error GoTo ERR_MDestroy
  45.    
  46.     Dim hHeap As Long
  47.    
  48.     '*************************************************************************
  49.     '* Derference the matrix header's heap record, and release the heap . . .
  50.     '*************************************************************************
  51.     hHeap = MemLong(pMatrix + 12)
  52.     HeapDestroy hHeap
  53.    
  54.     Exit Sub
  55.    
  56. ERR_MDestroy:
  57.     Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext
  58. End Sub
  59. Public Function MSMultiply(Scalar As Single, pMatrix As Long) As Long
  60.     On Error GoTo ERR_MSMultiply
  61.     Dim pMem1 As Long
  62.     Dim pMem2 As Long
  63.     Dim pMatrix2 As Long
  64.     Dim i As Long
  65.     Dim j As Long
  66.     Dim s As Long
  67.    
  68.     '******************************************
  69.     '* Get start of memory block and size . . .
  70.     '******************************************
  71.     pMem1 = pMatrix + 16
  72.     s = MemLong(pMatrix + 8)
  73.    
  74.     '*************************************************************
  75.     '* Copy dimensions of source matrix, and use 'em for the return
  76.     '* one . . .
  77.     '*************************************************************
  78.     i = MemLong(pMatrix)
  79.     j = MemLong(pMatrix + 4)
  80.     pMatrix2 = MCreate(i, j)
  81.     pMem2 = pMatrix + 16
  82.    
  83.     '****************************
  84.     '* Perform the multiply . . .
  85.     '****************************
  86.     For i = 0 To s Step 4
  87.         MemSingle(pMem2 + i) = (MemSingle(pMem1 + i) * Scalar)
  88.     Next
  89.    
  90.     '************************************
  91.     '* Return pointer to new matrix . . .
  92.     '************************************
  93.     MSMultiply = pMatrix2
  94.    
  95.     Exit Function
  96.    
  97. ERR_MSMultiply:
  98.     Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext
  99. End Function

This avoids many VB things that could be considered slow. To be fair, you'd probably want to write this lot in C and implement it in a DLL that VB can access: I only wrote this to play with the MemLong function (and to test it's speed)

This fragment avoids SAFEARRAY overheads, and other VB safety features by directly allocating some memory, and then manipulating it according to various matrix rules. SAFEARRAYS are not great for dealing across different threads in a process with such wonderful features such as cbLocks in it's descriptor, and the automatic teardown code that goes with SAFEARRAYS (which, btw, makes VB marvellously simple and safe for beginners and experts alike)

Also, ideally, the memory needs to be allocated on the stack, rather than the heap, but - hey: one step at a time.

It also creates a completly arbitrary descriptor (I invented it, if you like) to describe the matrix structure. Which means the thread only needs to have a copy of the descriptor, and not the body of data. You can effectively pass around the descriptor instead of the data.

You can replace the vast majority of MemLong, and MemSingle calls in this fragment with CopyMemory calls - so hopefully you can see the advantage in using it. Normally, though, you'd be using CopyMemory to directly access parts of VB's internal system as in this example:

VB Code:
  1. Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, source As Any, ByVal Length As Long)
  2. Public Type SafeArray1d
  3.     cDims As Integer
  4.     fFeatures As Integer
  5.     cbElements As Long
  6.     cLocks As Long
  7.     pvData As Long
  8.     cElements As Long
  9.     lLbound As Long
  10. End Type
  11. Public Const ARRAY_NOT_INITIALISED As Long = -1
  12. Public Function MaxOrdinal(ppSA As Long) As Long
  13.    
  14.     ' Eg: n = MaxOridinal(VarPtrArray(MyArray))
  15.    
  16.     Dim SA As SafeArray1d
  17.     Dim pSA As Long
  18.     '***********************************************
  19.     '* Deref ppSA. C equivalent: = pSa=*ppSA . . .
  20.     '***********************************************
  21.     CopyMemory pSA, ByVal ppSA, 4
  22.    
  23.     '*****************************************************
  24.     '* If we have a pointer then check to see how
  25.     '* many elements we are allowed. If the array
  26.     '* is not dimensioned then pSA will not be valid . . .
  27.     '*****************************************************
  28.     If pSA Then
  29.         CopyMemory SA, ByVal pSA, LenB(SA)
  30.         MaxOrdinal = (SA.cElements - 1)
  31.     Else
  32.         MaxOrdinal = ARRAY_NOT_INITIALISED
  33.     End If
  34.    
  35. End Function

which returns the highest ordinal allocated in an a single dimensional array, and ARRAY_NOT_INITIALISED if the array is not allocated yet; this is incredibly useful in production code, as well as being extremely fast.
__________________
"As far as the laws of mathematics refer to reality, they are not certain; and as far as they are certain, they do not refer to reality." - Albert Einstein

It's turtles! And it's all the way down


Thoughts

Last edited by yrwyddfa; Mar 22nd, 2006 at 05:19 AM.
yrwyddfa is offline   Reply With Quote
Reply

Go Back   VBForums > Visual Basic > API


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -5. The time now is 05:22 AM.





Acceptable Use Policy

Internet.com
The Network for Technology Professionals

Search:

About Internet.com

Legal Notices, Licensing, Permissions, Privacy Policy.
Advertise | Newsletters | E-mail Offers

Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.