Speicherzugriff

04/05/2009 - 12:46 von Thomas Freudenreich | Report spam
Hallo! Ich arbeite mit VB2005 .NET 2.0 und versuche bei einer Long
Variablen im Speicher 2 Stellen zu vertauschen. Dazu habe ich folgendes
versucht:
Private Declare Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" (ByVal
Destination As Long, ByVal Source As Long, ByVal Length As Integer)

Dim l1 as Long = 0L
CopyMem( l1, l1, 1)

Ich hàtte jetzt erwartet das ich eine Exception erhalte da ich versuche
auch Adresse 0 zuzugreifen, aber VB übergibt scheinbar auch beim
elementarem Longtyp nicht den Inhalt sondern einen Zeiger auf die Variable.
Kann ich das irgendwie umgehen. Am Ende soll die Routine so aussehen:

Dim GC As GCHandle = GCHandle.Alloc(e, GCHandleType.Pinned)
Dim GC2 As Integer = GC.AddrOfPinnedObject.ToInt32
CopyMem( GC2+1, GC2, 1)
GC.Free()

In VB6 klappt es wenn ich CopyMem( ByVal GC2+1, ByVal GC2, 1) schreibe
aber das gibt es wohl anscheinend nicht mehr.

Thomas
 

Lesen sie die antworten

#1 Armin Zingler
04/05/2009 - 13:05 | Warnen spam
Thomas Freudenreich wrote:
Hallo! Ich arbeite mit VB2005 .NET 2.0 und versuche bei einer Long
Variablen im Speicher 2 Stellen zu vertauschen. Dazu habe ich
folgendes versucht:
Private Declare Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory"
(ByVal Destination As Long, ByVal Source As Long, ByVal Length As
Integer)



Die Deklaration ist schon mal falsch. Das làuft weder auf einem 32-Bit noch
auf einem 64-Bit Windows, weil du Long und Integer mischst. Richtig:

Private Declare Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory"
(ByVal Destination As IntPtr, ByVal Source As IntPtr, ByVal Length As
IntPtr)


Dim l1 as Long = 0L
CopyMem( l1, l1, 1)

Ich hàtte jetzt erwartet das ich eine Exception erhalte



Möglicherweise macht CopyMemory nichts, weil Source=Destination. In der Doku
steht: "If the source and destination blocks overlap, the results are
undefined".

da ich
versuche auch Adresse 0 zuzugreifen, aber VB übergibt scheinbar auch
beim elementarem Longtyp nicht den Inhalt sondern einen Zeiger auf
die Variable. Kann ich das irgendwie umgehen. Am Ende soll die
Routine so aussehen:

Dim GC As GCHandle = GCHandle.Alloc(e, GCHandleType.Pinned)
Dim GC2 As Integer = GC.AddrOfPinnedObject.ToInt32



Du weisst, dass du dann Win32 als Target Platform bei den Projektoptionen
angeben musst (weil ToInt32 und nicht ToInt64)? Wenn du gleich IntPtr in der
Deklaration verwendest, dann musst du dich aber darum nicht kümmern und
verwendest direkt GC.AddrOfPinnedObject.

CopyMem( GC2+1, GC2, 1)
GC.Free()

In VB6 klappt es wenn ich CopyMem( ByVal GC2+1, ByVal GC2, 1)
schreibe aber das gibt es wohl anscheinend nicht mehr.



Tja, Pointer-Operationen sind in der ("sicheren") verwalteten Welt quasi
ausgestorben. Dein Beispiel begründet aber auch, warum. Kannst du dich evtl
mit der [System.Runtime.InteropServices.]Marshal.Copy-Methode anfreunden?


Armin

Ähnliche fragen