Lupin003 09-07-2003, 12:49 PM I want to use an array as an memory pointer, i have an adress stored into an long value and now I want my dummie array to point to that address, I think that should work as long as array bounds checking is off.
I think I'd have to use CopyMemory to copy the address to whereever the address of my array is stored.... but that's my actual problem - where's the adress of the data my array points to? And how to do all this???
OnErr0r 09-07-2003, 01:10 PM You can use the SafeArray hack for that, here's the module I use:
' begin modSafeArray.bas
Option Explicit
Public Type SAFEARRAYBOUND ' 8 bytes
cElements As Long
lLbound As Long
End Type
Public Type SAFEARRAYHEADER ' 20 bytes (for one dimensional arrays
dimensions As Integer
fFeatures As Integer
DataSize As Long
cLocks As Long
dataPointer As Long
sab(1) As SAFEARRAYBOUND
End Type
Const FADF_AUTO = &H1& '// Array is allocated on the stack.
Const FADF_STATIC = &H2& '// Array is statically allocated.
Const FADF_EMBEDDED = &H4& '// Array is embedded in a structure.
Const FADF_FIXEDSIZE = &H10& '// Array may not be resized or reallocated.
Const FADF_BSTR = &H100& '// An array of BSTRs.
Const FADF_UNKNOWN = &H200& '// An array of IUnknown*.
Const FADF_DISPATCH = &H400& '// An array of IDispatch*.
Const FADF_VARIANT = &H800& '// An array of VARIANTs.
Const FADF_RESERVED = &HF0E8& '// Bits reserved for future use.
Public Enum eDATASIZE
byteArray = 1
integerArray = 2 ' or Boolean Data Type
longArray = 4
singleArray = 4
doubleArray = 8
End Enum
'Public Declare Function VarPtrArray Lib "msvbvm50.dll" Alias "VarPtr" (Var() As Any) As Long
Public Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" (Var() As Any) As Long
Public Function RedimArray(ByVal DataSize As eDATASIZE, ByVal lNumElements As Long, ByRef sa As SAFEARRAYHEADER, ByVal lDataPointer As Long, ByVal lArrayPointer As Long, Optional LoBound As Long = 0) As Long
If lNumElements > 0 And lDataPointer <> 0 And lArrayPointer <> 0 Then
With sa
.DataSize = DataSize ' byte = 1 byte, integer = 2 bytes etc
.dimensions = 1 '2 ' one dimensional
.dataPointer = lDataPointer ' to unicode string data (or other?)
.sab(0).lLbound = LoBound ' lower bound
.sab(0).cElements = lNumElements ' number of elements
'.sab(1).cElements = lNumElements
'.sab(1).lLbound = LoBound
RtlMoveMemory ByVal lArrayPointer, VarPtr(sa), 4& ' fake VB out
RedimArray = True
End With
End If
End Function
Public Sub DestroyArray(ByVal lArrayPointer As Long)
Dim lZero As Long
RtlMoveMemory ByVal lArrayPointer, lZero, 4 ' put the array back to its original state
End Sub
Lupin003 09-07-2003, 01:15 PM ok, but how could I find out lDataPointer and lArrayPointer? Does VB still use the same structure when not checking array bounds?
Why do you only copy 4 bytes to the Array pointer and not 20?
OnErr0r 09-07-2003, 01:25 PM lArrayPointer comes from VarPtrArray. Save it to pass to DeleteArray also.
lDataPointer is VarPtr(foo(firstElement) or in your case, the pointer you have to your data.
Copying 4 bytes to make VB use our "fake" SafeArray structure.
Lupin003 09-07-2003, 01:50 PM This means, I'm not actually manipulating VB's safe array structure I'm just advising VB to use my safe array structure instead of the original one? Isn't there an way to find out where the real struct resists?
Ok, What flags do I have to define in my case? I'm wondering why there are even flags, for me memory is just memory, there shouldn't be any difference between dynamic one and static one or so...
Thx for your help!
OnErr0r 09-07-2003, 01:56 PM VarPtrArray is the pointer to the safearray struct. It's easiest just to temporarily point to your own sa.
You shouldn't have to worry about flags, if you're not passing this "fake" array.
Lupin003 09-07-2003, 02:35 PM I don't get it.... does the RtlMoveMemory function have to be declared in an special way?
My app always crashes, it seems to have no effect... Here's some of my code:
'These are my dummie arrays I want to use to safe the data
'each array has an SAFEARRAYHEADER containing the informations
'and an pointer to the actual data of the array
Private VertPos(0) As vBPoint
Private sah_pos As SAFEARRAYHEADER
Private pPos As Long
'
Private VertPV(0) As vPVData
Private sah_pv As SAFEARRAYHEADER
Private pPV As Long
'
Private VertMV(0) As vMVData
Private sah_mv As SAFEARRAYHEADER
Private pMV As Long
'Create the memory buffers and lock them
Set bBPoint = D3Ddevice.CreateVertexBuffer(vBP_size * numVerts, 0, 0, D3DPOOL_MANAGED)
bBPoint.Lock 0, vBP_size * numVerts, pPos, 0
Set bMVData = D3Ddevice.CreateVertexBuffer(vMV_size * numVerts, 0, 0, D3DPOOL_MANAGED)
bMVData.Lock 0, vMV_size * numVerts, pMV, 0
Set bPVData = D3Ddevice.CreateVertexBuffer(vPV_size * numVerts, 0, 0, D3DPOOL_MANAGED)
bPVData.Lock 0, vPV_size * numVerts, pPV, 0
'Set up the dummie arrays
RedimArray vBP_size, numVerts, sah_pos, pPos, VarPtrArray(VertPos())
RedimArray vMV_size, numVerts, sah_mv, pMV, VarPtrArray(VertMV())
RedimArray vPV_size, numVerts, sah_pv, pPV, VarPtrArray(VertPV())
Dim rVert As BSPvertex 'This is the vertex I read out of my file
....read out the info out of the file and store into my dummie arrays VertMV, VertPV and VertPos
do you have any idea what's the problem here?
OnErr0r 09-07-2003, 03:45 PM Two things I see right off. First, Dim the arrays as dynamic. Second, call DestroyArray before the end of the procedure.
Lupin003 09-08-2003, 08:42 AM Wow, it works! These "pointers" are very usefull! Could I also set an normal variable to point to another memory location?
OnErr0r 09-09-2003, 09:27 AM Long variables are 32bits and can contain pointers to memory locations.
|