CopyMemory oder Ersatz für VB.net

  • VB.NET
  • .NET (FX) 3.0–3.5

Es gibt 31 Antworten in diesem Thema. Der letzte Beitrag () ist von Gonger96.

    CopyMemory oder Ersatz für VB.net

    Hallo Gemeinde,

    ich bekomme folgenden Fehler
    System.AccessViolationException ist aufgetreten.
    Message="Es wurde versucht, im geschützten Speicher zu lesen oder zu schreiben. Dies ist häufig ein Hinweis darauf, dass anderer Speicher beschädigt ist."

    Im Moment versuche ich ein altes VB6 Programm in VB.Net umzuschreiben

    Dabei wurde in VB6 folgende Api Funktion verwendet
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal Destination As Integer, ByVal Source As String, ByVal Length As Integer)

    Folgender Funktionsaufruf:

    Public Function StringAsLong(ByVal sValue As String) As Long
    '4 Byte-String als 32 Bit-Wert
    Dim l As Long

    CopyMemory l, ByVal sValue, 4
    StringAsLong = l

    End Function
    Bei einem sValue = "1000" lieferte die Funktion den Wert 1 zurück.

    kleine Korrektur:
    Die Werte 1000 sind Byte Werte die im String mit komischen Zeichen dargestellt werden.





    ich versuche nun dieses in VB.Net umzusetzen. Jedoch scheitere ich gerade an der oberen Fehlermeldung.

    Mein Code:

    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal Destination As Integer, ByVal Source As String, ByVal Length As Integer)

    Private Sub Test()
    Dim sString As String
    Dim iInteger As Integer

    sString = "1000"

    iInteger = StringAsInteger(sString)
    End Sub

    Private Function StringAsInteger(ByVal sValue As String) As Integer
    '4 Byte-String als 32 Bit-Wert
    Dim l As Integer
    CopyMemory(l, sValue, 4)
    Return l

    End Function


    Liegen die Speicherbereiche für Variablen in einem geschützen Speicher?
    Gibt es einen VB.net Weg für CopyMemory?

    Grüße
    Tim

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Codrix“ ()

    Codrix schrieb:

    VB.NET-Quellcode

    1. Private Function StringAsInteger(ByVal sValue As String) As Integer
    Was genau soll denn in dieser Funktion passieren?
    Ein VB6-String hat 1 Byte pro Zeichen, ein .NET-String hat 2 Byte pro Zeichen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @Codrix Fein. :rolleyes:
    Ich meinte Deine Funktion StringAsInteger().
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany
    Gell hab ich Dir Toll erklärt was CopyMemory macht. Aber Du hast ja nach StringAsInteger() gefragt. Interessanter Weise macht die Funktion nichts anderes als CopyMemory aufzurufen und den Wert davon zurückzugeben als Integer. Aber das hättest Du sicher gesehen wenn Du die Funktion genau gelesen hättest. Aber versteh ich man hat halt nicht so viel Zeit.
    ;)


    @diylab
    Danke der dritte Link hat mir weitergeholfen.

    --------------------------------
    Private Sub Test()

    Dim LongValue As Integer
    Dim ByteArray(3) As Byte

    ByteArray(0) = 1
    ByteArray(1) = 0
    ByteArray(2) = 0
    ByteArray(3) = 0

    'Create Gchandle instance and pin variable required
    Dim MyGC As GCHandle = GCHandle.Alloc(LongValue, GCHandleType.Pinned)
    'get address of variable in pointer variable
    Dim AddofLongValue As IntPtr = MyGC.AddrOfPinnedObject()
    'Use copy method to copy array data to variable’s
    'address with length specified(4)
    Marshal.Copy(ByteArray, 0, AddofLongValue, 4)
    'First read value of variable from its address
    'in memory in order to use it
    LongValue = Marshal.ReadInt32(AddofLongValue)
    'Print to output window
    Debug.WriteLine("Value of LongValue is: " & LongValue)
    'Free GChandle to avoid memory leaks
    MyGC.Free()

    End Sub
    -------------------------

    Der Link zur Erklärung
    codeproject.com/Articles/8641/…lent-of-CopyMemory-in-NET

    Codrix schrieb:

    This results in an ultra fast copy of data.
    Das dürfte nun allerdings nicht mehr gewährleistet sein. ;)
    Insbesondere für den Spezialfall von 4 Bytes ist das die pure Onanie.
    Da würde ich mir eher eine native .Net-Funktion dafür suchen, z.B. Convert.ToInt32

    Edit: Am besten BitConverter.Int32
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „petaod“ ()

    ob das jetzt immer noch ultraschnell sein soll war mir jetzt nicht so wichtig solange es funktioniert.

    Hab Deinen vorschlag mal probiert

    "Das Objekt des Typs "System.Byte[]" kann nicht in Typ "System.IConvertible" umgewandelt werden."

    wäre mir natürlich auch lieber wenn ich das mit mit einem Einzelner machen könnte :)

    Codrix schrieb:

    genau gelesen hättest
    Wieder Fein.
    Du schiebst die ASCII-Codes der Zeichen in einen Integer.
    Wozu?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Das macht Deine Funktion

    Codrix schrieb:

    StringAsInteger()

    Codrix schrieb:

    Gell hab ich Dir Toll erklärt was CopyMemory macht.
    Hast aber gar nix verstanden, was Dein Programm macht. ;(
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Was Rod von Anfang an sagen wollte: Deine Umsetzung ist ziemlich sinnbefreit und sieht für mich nach einer tausendfachen Komplizierung von bereits existieren Net Funktionen aus. Vielleicht hat dieser API AUfruf in VB6 noch Sinn gemacht, aber das Wort für WOrt zu übersetzen ist einfach blöd.

    Skybird schrieb:

    Das sind ja Ubisoftmethoden hier !

    In meinem ersten Beitrag hab ich gefragt

    Gibt es einen VB.net Weg für CopyMemory?


    Interessant das es Leute gibt die die Frage verstehen ohne über den Sinn nachzudenken...

    Wieso müsst ihr ewig über sinn und zweck einer Sache diskutieren???
    Geht euch dabei einer ab???

    Dann bin ich halt blöd. Werd ich dadurch schlaflose Nächte haben.... nein!
    Tut den "Normalen" Foren Benutzern, nicht nur hier im Forum sondern auch in anderen Foren, einen Gefallen. Wenn Ihr nichts zu sagen habt, dann behalten Eure Meinung für Euch! Es ist weder hilfreich noch konstruktiv.
    <X
    Aha, natürlich, alle vorherigen Beiträge haben Dir doch bereits geholfen/weiterhelfen wollen und nur, weil jetzt jemand anspricht, dass das bestimmt einfacher ginge, was einfach nur richtig ist, dann ist das nicht konstruktiv?
    Das gehört zur Programmierung dazu. Programmieren ist nicht nur irgendwas hinklatschen und sagen, "Es geht!", sondern viel mehr, man muss über Performance, Architektur etc. nachdenken, sonst kriegt man evtl mal Probleme.

    btw: Das "Blöd" war doch nicht mal auf Dich bezogen, ich verstehe nicht, warum Du das jetzt so verstanden hast, denn es hieß nur, dass der Weg es so zu machen blöd wäre, also nicht gut auf deutsch.
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:

    Codrix schrieb:


    .....
    Wieso müsst ihr ewig über sinn und zweck einer Sache diskutieren???
    ....
    Tut den "Normalen" Foren Benutzern, nicht nur hier im Forum sondern auch in anderen Foren, einen Gefallen. Wenn Ihr nichts zu sagen habt, dann behalten Eure Meinung für Euch! Es ist weder hilfreich noch konstruktiv.
    ....

    .. ging mit auch schon öfter durch den Kopf.
    Immer gleich die Frage.. wozu ..warum.. usw :) .. aber keine Antwort
    Najaa es ist immer gut zu wissen was jemand vor hat um ihm eine ggf. einfachere oder schönere Lösung vorschlagen zu können.
    So kann man jetzt nur spekulieren dass er einen String in einen Integer umwandeln möchte.

    Und einen String würde ich mit hilfe der Integer.TryParse bzw. Integer.Parse-Methoden in einen Integer konvertieren.
    lg.

    LucaWelker
    Ich fasse es mal zusammen:

    Der TE versucht erfolglos einen ranzigen uralt VB6 Code 1zu1 nach VB.NET zu konvertieren und beschwert sich dann, dass wir wissen wollen WAS er eigentlich machen will.
    Du musst verstehen, was dein alter Code eigentlich macht, damit du ihn in eine MODERNE Sprache übersetzen kannst.

    Danach baust du die Funktionalität mit den neueren sicheren besseren und kürzeren Werkzeugen aus dem .NET-Framework nach. (siehe Bitconverter)

    @LucaWelker
    Integer.TryParse ist die falsche Methode, falls er eine Bytefolge reinterpretiert.
    @Trade
    Ich hab nichts gegen Kritik. Bei Gott nicht.
    Vielleicht liegt es ja an mir dass ich mein Problem nicht so formulieren konnte das es verstanden wird.
    Aber wenn jemand mit "CopyMemory" was anfangen kann dann kann er mir auch eine Konstruktive Idee schreiben wie man das in VB.net einfacher schöner besser lösen kann. Nur zu sagen das es einfacher geht ist keine Hilfe.
    Oder täusch ich mich da?

    aber das Wort für WOrt zu übersetzen ist einfach blöd.

    Da ich das Wort für Wort übernommen hab, war ich ja so gesehen blöd... aber egal.
    inwiefern hilft mir sein Beitrag???

    @RoulettePilot
    Geht also nicht nur mir so :)

    @markus.obi
    Ja. Ich hab einen uralten VB6 Code.
    CopyMemory nimmt was von Speicherplatz "A" und kopiert diesen in Speicherplatz "B". Es wird nicht konvertiert. Und wie kopiert man den Speicherinhalt von "A" nach "B" in VB.Net?

    Ihr wollt den Hintergrund der ganzen Sache wissen?
    Ok. Hier wird ein Lizenzschlüssel ausgelesen. Am Anfang der Sache besteht der Schlüssel als ein ewig langer String... die funktion ist an die funktion ist aus... dieser String wird verschlüsselt. Danach hab ich eine noch länge Bytefolge mit allen Möglichen Werten drin, die aber in bestimmte Regionen aufgeteilt ist. Zum Beispiel stehen 4 Bytes an Startposition für eine Lizenz Version. CopyMemory nimmt sich diese 4 Byte und schreibt diese in den Speicherplatz von einer Variablen.

    Hätte sowas als info gereicht?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Codrix“ ()

    Du hast eine uralt ranzige Lösung von VB6 WORT für WORT in VB.NET übernommen.
    Du MUSST verstehen, was deine Funktion eigentlich macht. Was wird als Parameter übergeben, was wird zurück gegeben...

    Danach kannst du Funktion in VB.NET nachbauen.

    Das was damals in VB6 in furchtbar scheuslichem Code hingefrickelt wurde, geht jetzt in VB.NET viel einfacher und sicherer.

    Wenn du damit fertig bist, könnte so eine Frage rauskommen:
    Wie interpretier ich eine byte-Folge als LONG?
    Außerdem hat RodFromGermany auch schon einen wichtigen Hinweis gegeben:
    Ein VB6-String hat 1 Byte pro Zeichen, ein .NET-String hat 2 Byte pro Zeichen.

    Nun, ich gebe Dir recht, er hätte gleich eine entsprechende Lösung in Form eines Links zu was Geeignetem posten können o. ä., aber natürlich kannst Du Dich auch erkundigen. Das ist halt hier im Forum so. Auch sowas soll/muss als Hilfe aufgefasst werden, bei manchen Personen fühlt man sich evtl mal etwas härter angesprochen als bei anderen, aber zusammen ist es halt (meist) Kritik, keine Angriffe etc. pp. Der Ton macht halt die Musik. In diesem Fall war es aber nicht angreifend, vielleicht klingt das so, wenn man sich den Post (von vb-checker) nur ein mal durch liest, aber er hat nur die Tatsache mit VB6 angesprochen, das sollte nichts gegen Dich sein, sondern eine wichtige Info. ;)
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!: