By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,285 Members | 1,659 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,285 IT Pros & Developers. It's quick & easy.

API - CopyMemory

P: n/a
I am trying to use CopyMemory to copy arrays as follows:

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal
pDst As Long, ByVal pSrc As Long, ByVal ByteLen As Integer)

dim kin(11) as Integer
dim kout(11) as Integer

kin(1)= 1 'set values for two elements to see if Kout is the same
kin(5) = 5

CopyMemory(kout(0), kin(0), 48)

It compiles and runs but all I get in Kout is "0" for all elements.

--
Dennis in Houston
Nov 21 '05 #1
Share this Question
Share on Google+
10 Replies


P: n/a
"Dennis" <De****@discussions.microsoft.com> wrote in message
news:56**********************************@microsof t.com...
I am trying to use CopyMemory to copy arrays as follows:

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal
pDst As Long, ByVal pSrc As Long, ByVal ByteLen As Integer)

dim kin(11) as Integer
dim kout(11) as Integer

kin(1)= 1 'set values for two elements to see if Kout is the same
kin(5) = 5

CopyMemory(kout(0), kin(0), 48)

It compiles and runs but all I get in Kout is "0" for all elements.

--
Dennis in Houston


Try changing Long to Integer in the API declare. Looks like a VB6
declaration. VB6 Long = VB.Net Integer

--
Al Reid
Nov 21 '05 #2

P: n/a
Tried that, no change. I found an example on the web that timed the various
methods of copying arrays, i.e., for loop, assignment, and CopyMemory written
for vb.net. It doesn't work either as it only copies zeros. The author
apparently didn't test it by actually putting values in the source array.
--
Dennis in Houston
"Al Reid" wrote:
"Dennis" <De****@discussions.microsoft.com> wrote in message
news:56**********************************@microsof t.com...
I am trying to use CopyMemory to copy arrays as follows:

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal
pDst As Long, ByVal pSrc As Long, ByVal ByteLen As Integer)

dim kin(11) as Integer
dim kout(11) as Integer

kin(1)= 1 'set values for two elements to see if Kout is the same
kin(5) = 5

CopyMemory(kout(0), kin(0), 48)

It compiles and runs but all I get in Kout is "0" for all elements.

--
Dennis in Houston


Try changing Long to Integer in the API declare. Looks like a VB6
declaration. VB6 Long = VB.Net Integer

--
Al Reid

Nov 21 '05 #3

P: n/a
Dennis wrote:
Tried that, no change. I found an example on the web that timed the various
methods of copying arrays, i.e., for loop, assignment, and CopyMemory written
for vb.net. It doesn't work either as it only copies zeros. The author
apparently didn't test it by actually putting values in the source array.

I would have the that you should be passing by ref not by val but ....
Nov 21 '05 #4

P: n/a
"Dennis" <De****@discussions.microsoft.com> schrieb:
CopyMemory(kout(0), kin(0), 48)

It compiles and runs but all I get in Kout is "0" for all elements.


I am curious why you would want to use 'CopyMemory'. You may want to use
'Buffer.BlockCopy' instead, which is pretty fast.

--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://classicvb.org/petition/>

Nov 21 '05 #5

P: n/a
Dennis,

First, pDst and pSrc should be declared as ByRef. They are pointers, and
passing pointers ByVal doesn't make much sense.
Second, their type must match the type of an array.

So, your declatation should look like:

~
Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" ( _
ByRef Destination As Integer, _
ByRef Source As Integer, _
ByVal Length As Integer _
)
~

Third, you can declare them as arrays, so it will be:

~
Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" ( _
<MarshalAs(UnmanagedType.LPArray)> ByVal Destination() As
Integer, _
<MarshalAs(UnmanagedType.LPArray)> ByVal Source() As Integer, _
ByVal Length As Integer _
)
~

Fourth, why don't you use the Array.Copy method?

Roman

"Dennis" <De****@discussions.microsoft.com> /
: news:56**********************************@microsof t.com...
I am trying to use CopyMemory to copy arrays as follows:

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal pDst As Long, ByVal pSrc As Long, ByVal ByteLen As Integer)

dim kin(11) as Integer
dim kout(11) as Integer

kin(1)= 1 'set values for two elements to see if Kout is the same
kin(5) = 5

CopyMemory(kout(0), kin(0), 48)

It compiles and runs but all I get in Kout is "0" for all elements.

--
Dennis in Houston

Nov 21 '05 #6

P: n/a
Thanks for the corrections to my code. You are absolutely correct in that I
need byRef. However, on the type in the declaration of CopyMemory, when
passed by reference, isn't an integer or long passed to the Com routine as
the address? For example, if my array is of type byte and I pass the array
by reference, what is actually passed...isn't it a 4 byte address?

As for using Array.CopyTo, in the end, I actually will be using CopyMemory
to copy a structure into an array for use with another com object.
--
Dennis in Houston
"Dragon" wrote:
Dennis,

First, pDst and pSrc should be declared as ByRef. They are pointers, and
passing pointers ByVal doesn't make much sense.
Second, their type must match the type of an array.

So, your declatation should look like:

~
Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" ( _
ByRef Destination As Integer, _
ByRef Source As Integer, _
ByVal Length As Integer _
)
~

Third, you can declare them as arrays, so it will be:

~
Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" ( _
<MarshalAs(UnmanagedType.LPArray)> ByVal Destination() As
Integer, _
<MarshalAs(UnmanagedType.LPArray)> ByVal Source() As Integer, _
ByVal Length As Integer _
)
~

Fourth, why don't you use the Array.Copy method?

Roman

"Dennis" <De****@discussions.microsoft.com> ÓÏÏÂÝÉÌ/ÓÏÏÂÝÉÌÁ × ÎÏ×ÏÓÔÑÈ
ÓÌÅÄÕÀÝÅÅ: news:56**********************************@microsof t.com...
I am trying to use CopyMemory to copy arrays as follows:

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory"

(ByVal
pDst As Long, ByVal pSrc As Long, ByVal ByteLen As Integer)

dim kin(11) as Integer
dim kout(11) as Integer

kin(1)= 1 'set values for two elements to see if Kout is the same
kin(5) = 5

CopyMemory(kout(0), kin(0), 48)

It compiles and runs but all I get in Kout is "0" for all elements.

--
Dennis in Houston


Nov 21 '05 #7

P: n/a
Thanks, you are correct in that I should be using byref. I was trying code
from an example I got from the net (it didn't work either) and that's why.
--
Dennis in Houston
"Jack Russell" wrote:
Dennis wrote:
Tried that, no change. I found an example on the web that timed the various
methods of copying arrays, i.e., for loop, assignment, and CopyMemory written
for vb.net. It doesn't work either as it only copies zeros. The author
apparently didn't test it by actually putting values in the source array.

I would have the that you should be passing by ref not by val but ....

Nov 21 '05 #8

P: n/a
Thanks Herfried but in the end, I want to copy a structure into an array
contained in another array for passing to another com object. That's why I
didn't use Buffer class.
--
Dennis in Houston
"Herfried K. Wagner [MVP]" wrote:
"Dennis" <De****@discussions.microsoft.com> schrieb:
CopyMemory(kout(0), kin(0), 48)

It compiles and runs but all I get in Kout is "0" for all elements.


I am curious why you would want to use 'CopyMemory'. You may want to use
'Buffer.BlockCopy' instead, which is pretty fast.

--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://classicvb.org/petition/>

Nov 21 '05 #9

P: n/a
"Dennis" <De****@discussions.microsoft.com> /
: news:32**********************************@microsof t.com...
Thanks for the corrections to my code. You are absolutely correct in that I need byRef. However, on the type in the declaration of CopyMemory, when passed by reference, isn't an integer or long passed to the Com routine as the address? For example, if my array is of type byte and I pass the array by reference, what is actually passed...isn't it a 4 byte address?
First, CopyMemory isn't a COM routine. 8=]

Yes, passing ByRef means passing IntPtr (platform-dependent integer)
value which represents address of a variable, so if you wanted to
specify an address (ByVal), you should declare it as IntPtr. But when
you declare parameter ByRef you specify a type of variable itself, not
type of pointer to it, don't you?

If you pass an array by reference you get garbage 8=]. You can either
pass its first element by reference, or pass the whole array by value.
You will get the same result though.

As for using Array.CopyTo, in the end, I actually will be using CopyMemory to copy a structure into an array for use with another com object.
You can use Marshal.StructureToPtr() method for this, for example:

~
Dim a(Marshal.SizeOf(GetType(Decimal)) - 1) As Byte
Marshal.StructureToPtr(23568.23573D,
Marshal.UnsafeAddrOfPinnedArrayElement(a, 0), False)
Stop
~
--
Dennis in Houston


Roman
Nov 21 '05 #10

P: n/a
Dennis,
Rather then risk memory, or at least to minimize, memory corruption.

I would recommend using Buffer.BlockCopy to copy arrays (as you initially
asked).

Alternatively I would use Marshal.Copy, Marshal.PtrToStructure,
Marshal.StructureToPtr and possible other methods on the
System.Runtime.InteropServices.Marshal class to marshal from the Managed to
Unmanaged world.

I would not attempt to implement my own marshaller with CopyMemory as the
..NET Framework team has already done the work for me...

--
Hope this helps
Jay
T.S. Bradley - http://www.tsbradley.net
"Dennis" <De****@discussions.microsoft.com> wrote in message
news:56**********************************@microsof t.com...
|I am trying to use CopyMemory to copy arrays as follows:
|
| Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal
| pDst As Long, ByVal pSrc As Long, ByVal ByteLen As Integer)
|
| dim kin(11) as Integer
| dim kout(11) as Integer
|
| kin(1)= 1 'set values for two elements to see if Kout is the same
| kin(5) = 5
|
| CopyMemory(kout(0), kin(0), 48)
|
| It compiles and runs but all I get in Kout is "0" for all elements.
|
| --
| Dennis in Houston
Nov 21 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.