Quantcast
Channel: VBForums - CodeBank - Visual Basic 6 and earlier
Viewing all articles
Browse latest Browse all 1448

UDT to String and Vice-Versa

$
0
0
This occasionally comes up when we need to get a UDT into a String, and back again. We may want to do this for inter-process communications, or maybe to easily get it into a Variant or Collection, or several other reasons.

One way is to serialize it with a named pipe. This is effectively the same as writing the UDT to a file, and then opening the file as Binary and reading in the bytes, and then stuffing them into a String.

However, it doesn't need to be this complicated. We can just directly copy the UDT into our string. And that's what I've outlined. As a note, any internal and/or external padding should be handled just fine, as LenB picks that up.

Here's some code for a BAS module to do this:
Code:


Option Explicit
'
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
'
Public Type TestUdtType
    s1 As String * 5
    s2 As String * 5
    i1 As Long
    d1 As Double
End Type
'

Public Function StringFromUdt(u As TestUdtType) As String
    StringFromUdt = String$((LenB(u) + 1&) \ 2&, vbNullChar)
    CopyMemory ByVal StrPtr(StringFromUdt), u, LenB(u)    ' On odd length UDTs, it won't completely fill the last Unicode character, but that's fine.
End Function

Public Function UdtFromString(s As String) As TestUdtType
    If Len(s) <> (LenB(UdtFromString) + 1&) \ 2& Then Err.Raise 13&, , "String isn't correct length for this UDT"
    CopyMemory UdtFromString, ByVal StrPtr(s), LenB(UdtFromString)
End Function


And here's a bit of test code you can put into a Form1:
Code:


Option Explicit

Private Sub Form_Load()
    Dim u As TestUdtType
    u.s1 = "asdf"
    u.s2 = "qwer"
    u.i1 = 1234
    u.d1 = 5.678

    Dim s As String
    s = StringFromUdt(u)
    Debug.Print s
    Dim u2 As TestUdtType
    u2 = UdtFromString(s)
    Debug.Print u2.s1, u2.s2, u2.i1, u2.d1

End Sub


Ok yes, I understand that this is specific to any particular UDT. But that's sort of always the case with these UDTs. To use this, just patch in your UDT declaration (instead of the "Public Type TestUdtType" declaration), and then search-and-replace all occurrences of TestUdtType with the name of your UDT, and you're all set.

In fact, if you've got several UDTs you wish to do this with, you can just make multiple copies of the StringFromUdt and UdtFromString functions, and name them different names to denote your UDT names.

-----------

This isn't complicated stuff, but it is something that comes up somewhat often.

Also, as a caveat, you probably shouldn't do this with UDTs that contain pointers (to BSTR Strings, objects, and/or dynamic arrays). It will still work, but UDTs with pointers must be handled with great care when copying them in any way other than a regular Let statement.

Viewing all articles
Browse latest Browse all 1448

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>