View Single Post
  #8   Report Post  
Posted to microsoft.public.excel.programming
Peter T[_7_] Peter T[_7_] is offline
external usenet poster
 
Posts: 162
Default Problem getting a pointer to a User Defined Type (UDT)


"Desmond Walsh" wrote in message
On Friday, May 25, 2018 at 4:34:39 AM UTC-4, Peter T wrote:
"Desmond Walsh" wrote in message

In my test code (in GetUdtPointer), I changed the value of the bmember2
property
first using the pointer marray(2).amember1.bmember2 and then using the
pointer GetUdtPointer.bmember2. Locals Window clearly showed 2 distinct
UDTb's being updated in the scope of GetUdtPointer. This led me to believe
that I could not return a pointer to a specific UDTb. But, when I switched
to a class definition of UDTb, I got the pointer I wanted.

Maybe I am missing a point. Could you modify the GetUdtPointer code to
return a pointer to a specific UDTb. That is all I was trying to do.

==============


I think you're missing the point about pointers!

Rather than explain maybe this illustrates using your UDTs -

' ' normal module
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" ( _
ByRef Destination As Any, _
ByRef Source As Any, _
ByVal Length As Long)
' this API needs adapting for use in 64bit Excel

Public Type Udtb
bmember1 As Integer ' 2 bytes
bmember2 As Integer ' 2 bytes
End Type ' total 4 bytes

Public Type Udta_v1
index As Integer 'bytes 1 to 2
amember1 As Udtb 'bytes 3 to 6
amember2 As Udtb 'bytes 7 to 10
End Type ' total 10 bytes


Sub test()
Dim bigU As Udta_v1, ba() As Byte, i As Long

bigU.index = 1
bigU.amember1.bmember1 = 2
bigU.amember1.bmember2 = 3
bigU.amember2.bmember1 = 4
bigU.amember2.bmember2 = 5

foo bigU, ba
Debug.Print bigU.amember1.bmember1 ' 5623
Debug.Print bigU.amember1.bmember2 ' 8223
Debug.Print bigU.amember2.bmember1 ' 10793
Debug.Print bigU.amember2.bmember2 ' 13363

For i = 0 To UBound(ba)
Debug.Print ba(i);
Next
' 1 2 21 22 31 32 41 42 51 52

End Sub

Sub foo(bigU As Udta_v1, ba() As Byte)
Dim uB1 As Udtb, n As Integer

bigU.index = 1 + 256 * 2

uB1.bmember1 = 21 + 256 * 22 ' 5623
uB1.bmember2 = 31 + 256 * 32 ' 8223

n = 41 + 256 * 42 ' 10793

CopyMemory ByVal VarPtr(bigU) + 2, uB1, 4
CopyMemory ByVal VarPtr(bigU) + 6, n, 2
CopyMemory ByVal VarPtr(bigU) + 8, (51 + 256 * 52), 2

ReDim ba(0 To LenB(bigU) - 1) ' 0 to 10 -1
CopyMemory ByVal VarPtr(ba(0)), bigU, LenB(bigU)

End Sub
' ' end code

While this is all straightforward with this set of UDTs with all declared
numeric members, be careful as with variants, strings (particularly if any
unicode) and arrays in UDTs internally, the data may not line up as simply
as in this example.

Your "GetUdtPointer" function is misnamed, it doesn't return a pointer. Also
there isn't a "pointer to a specific Utdb" as the specific Utdb you're
talking about doesn't exist until reconstructed, merely the relevant byte
offset from the main udt's pointer as illustrated. Just as series of bytes
any portion of which could be reconstrated to say a byte array or somthing
else.

If you explain the real objective for all this maybe there is a different
sort of answer.

Peter T