Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion GroupsVB SyntaxEnterprise DevelopmentDatabase AccessControlsCOMWin APICrystal ReportDeploymentGeneralGeneral 2
Related Topics
VB.NET / ASP.NETMS SQL ServerMS AccessOther Database ProductsMore Topics ...

VB Forum / COM / November 2005



Tip: Looking for answers? Try searching our database.

Convert user-defined data type to byte array?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Dick - 19 Oct 2005 17:30 GMT
can I convert user-defined data type to byte array?
Thanks.
MikeD - 19 Oct 2005 18:09 GMT
> can I convert user-defined data type to byte array?

You're gonna have to better explain what you mean or are wanting to do.
Post your UDT definition and even some code that somewhat shows what you're
wanting (even if it doesn't actually do it).

Signature

Mike
Microsoft MVP Visual Basic

Dick - 19 Oct 2005 19:06 GMT
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory"
(Destination As Any, Source As Any, ByVal Length As Long)
Private Type bb
   s As String * 20
End Type

Private Type uS
   a As Long
   b As Double
   c As String * 48
   d() As bb
End Type

'420 ×Ö½Ú
Private Sub Command1_Click()
Dim Data1()  As uS
Dim outArray() As Byte
Dim lTotalByte As Long

ReDim Data1(1)

lTotalByte = Len(Data1(0)) * (UBound(Data1) + 1)

Data1(0).a = 5
Data1(0).b = 8
Data1(0).c = "aa"
ReDim Data1(0).d(2) As bb
Data1(0).d(2).s = "vvvvv"

lTotalByte = lTotalByte + (UBound(Data1(0).d) + 1) * 20

Data1(1).a = 1
Data1(1).b = 1
Data1(1).c = "bb"
ReDim Data1(1).d(10) As bb
Data1(1).d(10).s = "ddddddd"
lTotalByte = lTotalByte + (UBound(Data1(0).d) + 1) * 20

ReDim outArray(lTotalByte - 1)
CopyMemory outArray(0), Data1(0), lTotalByte

MsgBox UBound(outArray)
MsgBox outArray(0)

Dim abc() As uS
ReDim abc(1)
ReDim Data1(0).d(2) As bb
ReDim Data1(1).d(10) As bb

CopyMemory abc(0), outArray(0), UBound(outArray)
MsgBox abc(1).d(10).s
End Sub

"MikeD" <nobody@nowhere.edu> ÎÅ:uCMyd$M1FHA.3188@TK2MSFTNGP14.phx.gbl...

> > can I convert user-defined data type to byte array?
>
[quoted text clipped - 5 lines]
> Mike
> Microsoft MVP Visual Basic
Schmidt - 20 Oct 2005 02:15 GMT
Serializing of VB-Types into ByteArrays per RtlMoveMemory is difficult, if
the type contains dynamic arrays or strings without Len-Def.
In both cases the VB-Type contains only Pointers to those members.

A solution for this problem is possible, if you work with VBs Put- and
Get-Statements against a NamedPipe.

'***Into a Form
Option Explicit

Private Declare Function CreateNamedPipe Lib "kernel32" Alias _
 "CreateNamedPipeA" (ByVal lpName As String, ByVal dwOpenMode&, _
  ByVal dwPipeMode As Long, ByVal nMaxInstances As Long, _
  ByVal nOutBufferSize As Long, ByVal nInBufferSize As Long, _
  ByVal nDefaultTimeOut As Long, lpSecurityAttributes As Any) As Long
Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, _
  lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, _
  lpNumberOfBytesWritten As Long, lpOverlapped As Any) As Long
Private Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, _
  lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, _
  lpNumberOfBytesRead As Long, lpOverlapped As Any) As Long
Private Declare Function PeekNamedPipe Lib "kernel32" (ByVal hNmdPipe&, _
  lpBuffer As Any, ByVal nBufferSize As Long, lpBytesRead As Long, _
  lpTotalBytesAvail As Long, lpBytesLeftThisMessage As Long) As Long
Private Declare Function DisconnectNamedPipe& Lib "kernel32"(ByVal hPipe&)
Private Declare Function CloseHandle& Lib "kernel32" (ByVal hObject&)

Private Type Test
 L As Long
 S As String
 B() As Byte
End Type

Private Sub Form_Click()
Dim T1 As Test, T2 As Test, B() As Byte
  T1.L = 123
  T1.S = "ABC"
  ReDim T1.B(3): T1.B(1) = 1: T1.B(2) = 2: T1.B(3) = 3

  Type2Bytes T1, B
  Bytes2Type B, T2
  Print T2.L, T2.S, T2.B(1); T2.B(2); T2.B(3)
End Sub

'results with the Count of written Bytes
Private Function Type2Bytes(T As Test, B() As Byte) As Long
Dim hPipe&, FNr&, Bytes&: Const PName$ = "\\.\pipe\Type2Bytes"
 hPipe = CreateNamedPipe(PName, 3, 0, 255, -1, -1, 0, ByVal 0&)
 If hPipe = -1 Then Exit Function

 FNr = FreeFile
 Open PName For Binary As FNr
 Put FNr, , T
 Close FNr

 PeekNamedPipe hPipe, ByVal 0&, 0, ByVal 0&, Bytes, ByVal 0&
 If Bytes > 0 Then
   ReDim Preserve B(Bytes - 1)
   ReadFile hPipe, B(0), Bytes, Bytes, ByVal 0&
   Type2Bytes = Bytes
 End If
 DisconnectNamedPipe hPipe
 CloseHandle hPipe
End Function

Private Function Bytes2Type(B() As Byte, T As Test) As Long
Dim hPipe&, FNr&, Bytes&: Const PName$ = "\\.\pipe\Bytes2Type"
 hPipe = CreateNamedPipe(PName, 3, 0, 255, -1, -1, 0, ByVal 0&)
 If hPipe = -1 Then Exit Function

 FNr = FreeFile
 Open PName For Binary As FNr

 WriteFile hPipe, B(0), UBound(B) + 1, Bytes, ByVal 0&
 If Bytes = UBound(B) + 1 Then Get FNr, , T: Bytes2Type = Loc(FNr)

 Close FNr
 DisconnectNamedPipe hPipe
 CloseHandle hPipe
End Function

Olaf
Dick - 20 Oct 2005 04:24 GMT
Thanks very much for you help!
:)

"Schmidt" <sss@online.de> :#3C6SRR1FHA.3504@TK2MSFTNGP10.phx.gbl...

> Serializing of VB-Types into ByteArrays per RtlMoveMemory is difficult, if
> the type contains dynamic arrays or strings without Len-Def.
[quoted text clipped - 78 lines]
>
> Olaf
Karl E. Peterson - 20 Oct 2005 18:42 GMT
Hi Olaf --

> A solution for this problem is possible, if you work with VBs Put- and
> Get-Statements against a NamedPipe.

That's really pretty cool!

But it also brings UniMess into the picture, right?  I mean, _if_ the UDT strings are
non-ANSI mappable (Unicode), you do run the risk of losing information, eh?

Still, for many purposes, well, I think I need to steal that! :-)

Thanks...   Karl
Signature

Working Without a .NET?
http://classicvb.org/petition

> '***Into a Form
> Option Explicit
[quoted text clipped - 72 lines]
>
> Olaf
Schmidt - 21 Oct 2005 11:53 GMT
> That's really pretty cool!
You name it... ;-)

Since we have reflection-mechanisms for COM-Classes in VB (Edanmos OleLib or
per tlbinf32.dll), wich allow something like that for the public Members of
Classes even at runtime - we have no *runtime*-reflection mechanism for VBs
TypeDefs.
At least *this* thing works at Type-Level, because the Put-Statement does
something, I would call a "Macro-Like-Type-Reflection" under the hood at
CompileTime.
Put needs to know the Type it serializes explicitly, so one cannot use those
functions in a "generic way" for all possible TypeDefs.
You have to define a separate conversion-Function (Ok, you have to
CopynPaste and change only the Type in the Function-Signature) for every
single Type that you want to serialize.
Anyway - this one is not bad for internal use inside Classes regarding
serialization to - and initializing from ByteStreams.

'***Inside a Class
Private Type InternalType
   PropA as String
   ...
End Type

Private m as InternalType

Public Property Get PropA() as String '(using 'm_'-Semantic)'
   PropA = m.PropA
End Property
Public Property Let PropA(NewVal as String)
   m.PropA = NewVal
End Property
'...
Public Property Get Content() as Byte()
   Type2Bytes m, Content
End Property
Public Property Let Content(NewVal() as Byte)
   Bytes2Type NewVal, m
End Property

Looks very clean and collects all internal Prop-Vars in one place (m).

> But it also brings UniMess into the picture, right?  I mean, _if_ the UDT strings are
> non-ANSI mappable (Unicode), you do run the risk of losing information, eh?
No real problem - those StringMembers, that need to be untouched by the
implicit ANSI-conversion, have to be defined as ByteArray inside the Type.

'***enhancing our Class-example above:
Private Type InternalType
   PropA as String
   PropUniString() as Byte
   '...
End Type
'...
Public Property Get PropUniString() as String
   PropUniString= m.PropUniString
End Property
Public Property Let PropUniString(NewVal as String)
   m.PropUniString = NewVal
End Property

In addition to that - for usage inside RPCs, that are implemented using a
fast, binary (maybe compressed) protocol; the implicit ANSI-Conversion is a
nice side-effect regarding the Send-/ReceiveBuffers size.

> Still, for many purposes, well, I think I need to steal that! :-)
:)

Olaf
Phil - 30 Nov 2005 14:42 GMT
> can I convert user-defined data type to byte array?

Yes, simply create another type containing a byte array of the correct size
and you can use LSet to copy the two udts to/from each other.
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.