ABOUT Visual Basic Programmieren Programmierung Download Downloads Tips & Tricks Tipps & Tricks Know-How Praxis VB VBA Visual Basic for Applications VBS VBScript Scripting Windows ActiveX COM OLE API ComputerPC Microsoft Office Microsoft Office 97 Office 2000 Access Word Winword Excel Outlook Addins ASP Active Server Pages COMAddIns ActiveX-Controls OCX UserControl UserDocument Komponenten DLL EXE
Diese Seite wurde zuletzt aktualisiert am 15.06.2001

Diese Seite wurde zuletzt aktualisiert am 15.06.2001
Aktuell im ABOUT Visual Basic-MagazinGrundlagenwissen und TechnologienKnow How, Tipps und Tricks rund um Visual BasicActiveX-Komponenten, Controls, Klassen und mehr...AddIns für die Visual Basic-IDE und die VBA-IDEVBA-Programmierung in MS-Office und anderen AnwendungenScripting-Praxis für den Windows Scripting Host und das Scripting-ControlTools, Komponenten und Dienstleistungen des MarktesRessourcen für Programmierer (Bücher, Job-Börse)Dies&Das...

Themen und Stichwörter im ABOUT Visual Basic-Magazin
Code, Beispiele, Komponenten, Tools im Überblick, Shareware, Freeware
Ihre Service-Seite, Termine, Job-Börse
Melden Sie sich an, um in den vollen Genuss des ABOUT Visual Basic-Magazins zu kommen!
Informationen zum ABOUT Visual Basic-Magazin, Kontakt und Impressum

Zurück...

Arrays zu Bytes

Zurück...


Anzeige

(-hg) mailto:hg_arraytobytearray@aboutvb.de

Für verschiedene Zwecke werden Sie vielleicht einmal ein Array eines beliebigen Datentyps (Integer, Long, Single, Double, Date oder Variant) als Byte-Array benötigen und dann gegebenenfalls von einem Byte-Array wieder in ein Array des ursprünglichen Datentyp zurück verwandeln müssen. Bei Arrays der genannten Datentypen bis auf Variant-Arrays ist das kein großes Problem. Bei Variant-Arrays gilt die Einschränkung, dass es nur Werte mit fester Byte-Länge enthalten darf, also Werte der übrigen genannten Datentypen.

Da die Byte-Längen der verschiedenen Datentypen festgelegt sind und die einzelnen Werte eines Arrays im Speicher hintereinander abgelegt sind, können die Bytes eines Arrays im Speicher direkt an die Stelle der Bytes eines Byte-Arrays kopiert werden. Dies erledigt die API-Funktion MSDN-Library - API RtlMoveMemory (CopyMemory)RtlMoveMemory, die wir der besseren Merkbarkeit halber unter dem Namen "CopyMemory" deklarieren:

Private Declare Sub CopyMemory Lib "kernel32" _
 Alias "RtlMoveMemory" (Dest As Any, Src As Any, _
 ByVal ByteLen As Long)

Ihr wird im ersten Parameter die Speicheradresse des ersten Elements des Ziel-Byte-Arrays übergeben, im zweiten Parameter die Speicheradresse des ersten Elements des zu kopierenden Arrays. Im dritten Parameter ist die Zahl der zu kopierenden Bytes anzugeben. Die Speicheradresse eines Array-Elements liefert Ihnen die (undokumentierte) Visual Basic-Funktion VarPtr.

Der Kopiervorgang sieht nun prinzipiell so aus:

CopyMemory ByVal VarPtr(Bytes(0)), ByVal VarPtr(Arr(0)), AnzahlBytes

Die expliziten ByVal-Angaben können Sie sich sparen, wenn Sie die ByVal-Direktiven gleich in der Deklaration von CopyMemory angeben. Zur Unterscheidung nennen wir die so deklarierte Funktion CopyMemoryV:

Private Declare Sub CopyMemoryV Lib "kernel32" _
 Alias "RtlMoveMemory" (ByVal Dest As Long, ByVal Src As Long, _
 ByVal ByteLen As Long)

CopyMemoryV VarPtr(Bytes(0)), VarPtr(Arr(0)), AnzahlBytes

Bevor Sie allerdings ein Array in ein Byte-Array kopieren können, müssen Sie dieses Byte-Array zunächst noch auf die erforderliche Größe bringen - es also entsprechend dimensionieren. Die Anzahl der Elemente eines Arrays ist gleich der Differenz zwischen Ober- und Untergrenze des Arrays plus 1. Zur Ermittlung der benötigten Größe des Byte-Arrays und damit auch der Anzahl der zu kopierenden Bytes ist die Anzahl der Elemente des Ausgangs-Arrays noch mit der Byte-Länge eines Elements dieses Arrays zu multiplizieren. Falls Sie beim Ziel-Byte-Array eine andere Untergrenze (Base) als 0 wünschen sollten, ist diese bei der Dimensionierung des Byt-Arrays entsprechend zu berücksichtigen.

Eine Hilfsfunktion, die ein Integer-Array in ein Byte-Array kopiert, sieht somit folgendermaßen aus:

Private Const kIntegerBytes = 2

Public Function IntegerArrToByteArr(Integers() As Integer, _
 Optional ByVal Base As Long) As Variant

  Dim nLBound As Long
  Dim nByteCount As Long
  Dim nBytes() As Byte
  
  nLBound = LBound(Integers)
  nByteCount = (UBound(Integers) - nLBound + 1) * kIntegerBytes
  ReDim nBytes(Base To nByteCount - 1 + Base)
  CopyMemoryV VarPtr(nBytes(Base)), VarPtr(Integers(nLBound)), _
   nByteCount
  IntegerArrToByteArr = nBytes
End Function

Als Rückgabewert der Funktion ist hier absichtlich der Datentyp Variant gewählt - Sie können die Funktion daher gleichermaßen sowohl unter Visual Basic 5 als auch 6 verwenden. Unter VB 6 können Sie den Rückgabewert natürlich auch direkt als Byte-Array deklarieren:

Public Function IntegerArrToByteArr(Integers() As Integer, _
 Optional ByVal Base As Long) As Byte()

Die Umkehrung der Funktion, also das Kopieren eines Byte-Arrays in ein Array eines anderes Datentyps beruht auf den gleichen Prinzipien. Sie ist jedoch nur sinnvoll, wenn das Byte-Array auch entsprechende Werte enthält - anderenfalls käme wohl nur Datenmüll zum Vorschein. Das Byte-Array enthält aber keinerlei Informationen darüber, woher seine Bytes stammen und welchen Datentyp sie letztendlich repräsentieren. Das einzige, was Sie sicherheitshalber prüfen können, ist die Anzahl der Bytes - diese muss sich durch die Byte-Länge des Ziel-Arrays teilen lassen (eine Modulo-Division muss den Rest 0 ergeben).

Auch bei der Umkehrfunktion können Sie wieder die Untergrenze (Base) des Ziel-Arrays festlegen. Die VB 6-Variante, die direkt ein Integer-Array zurückgibt, sieht so aus:

Public Function ByteArrToIntegerArr(Bytes() As Byte, _
 Optional ByVal Base As Long) As Integer()

  Dim nLBound As Long
  Dim nByteCount As Long
  Dim nIntegers() As Integer
  
  nLBound = LBound(Bytes)
  nByteCount = (UBound(Bytes) - nLBound + 1)
  If nByteCount Mod kIntegerBytes <> 0 Then
    Err.Raise kErrInvalidBytesCount
  Else
    ReDim nIntegers(Base To _
     (nByteCount \ kIntegerBytes) - 1 + Base)
    CopyMemoryV _
     VarPtr(nIntegers(Base)), VarPtr(Bytes(nLBound)), nByteCount
    ByteArrToIntegerArr = nIntegers
  End If
End Function

Da unter VB 5 nur Byte-Arrays als Rückgabewert einer Funktion übergeben werden können, muss die Umkehrfunktion hier als Prozedur mit einem zusätzlichen Parameter zur Übergabe des Ziel-Arrays angelegt werden:

Public Sub ByteArrToIntegerArr(Bytes() As Byte, _
 Integers() As Integer, Optional ByVal Base As Long)

  Dim nLBound As Long
  Dim nByteCount As Long
  
  nLBound = LBound(Bytes)
  nByteCount = (UBound(Bytes) - nLBound + 1)
  If nByteCount Mod kIntegerBytes <> 0 Then
    Err.Raise kErrInvalidBytesCount
  Else
    ReDim Integers(Base To _
     (nByteCount \ kIntegerBytes) - 1 + Base)
    CopyMemoryV _
     VarPtr(Integers(Base)), VarPtr(Bytes(nLBound)), nByteCount
  End If
End Sub

Den Code der entsprechenden Funktionen für die Datentypen Long, Single, Double, Date und Variant finden Sie in den Modulen, die Sie zu diesem Artikel herunterladen können.

Auch Arrays einer benutzerdefinierten Variablen (Type) können in ein Byte-Array kopiert werden. Als Elemente einer solchen Variablen sind auch Strings mit fester Länge als auch wiederum Arrays und sogar Verschachtelungen von benutzerdefinierten Variablen zulässig. Voraussetzung ist immer, dass letztlich alle Elemente eine feste Byte-Länge aufweisen. Damit Sie die Byte-Länge einer solchen benutzerdefinierten Variablen nicht selbst nachzählen müssen (wie leicht verzählt man sich dabei...), können Sie sie dynamisch über die VB-Funktion LenB ermitteln, der Sie eine hilfsweise deklarierte einzelne Variable des benutzerdefinierten Typs übergeben.

Public Type SampleType
  Byte As Byte
  Integer As Integer
  Long As Long
  Single As Single
  Double As Double
  Date As Date
  Variant As Variant
  String As String * 1
End Type

Public Function SampleTypeArrToByteArr(SampleTypes() As SampleType, _
 Optional ByVal Base As Long) As Byte()

  Dim nLBound As Long
  Dim nByteCount As Long
  Dim nBytes() As Byte
  Dim nSampleTypeBytes As Long
  Dim nSampleType As SampleType
  
  nSampleTypeBytes = LenB(nSampleType)
  nLBound = LBound(SampleTypes)
  nByteCount = (UBound(SampleTypes) - nLBound + 1) _
   * nSampleTypeBytes
  ReDim nBytes(Base To nByteCount - 1 + Base)
  CopyMemoryV VarPtr(nBytes(Base)), VarPtr(SampleTypes(nLBound)), _
   nByteCount
  SampleTypeArrToByteArr = nBytes
End Function

Hier wieder die abweichende Deklaration der Funktion für VB 5:

Public Function SampleTypeArrToByteArr(SampleTypes() As SampleType, _
 Optional ByVal Base As Long) As Byte()

Und die Gegenstücke, hier für VB 6:

Public Function ByteArrToSampleTypeArr(Bytes() As Byte, _
 Optional ByVal Base As Long) As SampleType()

  Dim nLBound As Long
  Dim nByteCount As Long
  Dim nSampleTypes() As SampleType
  Dim nSampleTypeBytes As Long
  Dim nSampleType As SampleType
  
  nSampleTypeBytes = LenB(nSampleType)
  nLBound = LBound(Bytes)
  nByteCount = (UBound(Bytes) - nLBound + 1)
  If nByteCount Mod nSampleTypeBytes <> 0 Then
    Err.Raise kErrInvalidBytesCount
  Else
    ReDim nSampleTypes(Base To _
     (nByteCount \ nSampleTypeBytes) - 1 + Base)
    CopyMemoryV VarPtr(nSampleTypes(Base)), _
     VarPtr(Bytes(nLBound)), nByteCount
    ByteArrToSampleTypeArr = nSampleTypes
  End If
End Function

und für VB 5:

Public Sub ByteArrToSampleTypeArr(Bytes() As Byte, _
 SampleType() As SampleType, Optional ByVal Base As Long)

  Dim nLBound As Long
  Dim nByteCount As Long
  Dim nSampleTypeBytes As Long
  Dim nSampleType As SampleType
  
  nSampleTypeBytes = LenB(nSampleType)
  nLBound = LBound(Bytes)
  nByteCount = (UBound(Bytes) - nLBound + 1)
  If nByteCount Mod nSampleTypeBytes <> 0 Then
    Err.Raise kErrInvalidBytesCount
  Else
    ReDim SampleTypes(Base To _
     (nByteCount \ nSampleTypeBytes) - 1 + Base)
    CopyMemoryV _
     VarPtr(SampleTypes(Base)), VarPtr(Bytes(nLBound)), nByteCount
  End If
End Sub

Module modArrayToByteArray (VB 5 und 6) (arraytobytearray.zip - ca. 2,7 KB)


Artikel
Zum Download-Bereich dieses Artikel
Mail an den Autor dieses Artikels

KnowHow
Zur KnowHow-Übersicht

KnowHow-Themen
Themen - Allgemeines
Themen - Entwicklungsumgebung (VB-IDE)
Themen - Forms
Themen - Steuerelemente (Controls)
Themen - Grafik
Themen - Dateien
Themen - UserControls
Themen - Einsteiger-Tipps
Themen - Wussten Sie...?

Übersicht nach Titeln in alphabetischer Reihenfolge
Übersicht nach Erscheinungsdatum

Schnellsuche




Zum Seitenanfang

Copyright © 1999 - 2017 Harald M. Genauck, ip-pro gmbh  /  Impressum

Zum Seitenanfang

Zurück...

Zurück...

Download Internet Explorer