Pointer to an array inside of a structure

Just starting out? Need help? Post your questions and find answers here.
User avatar
Demivec
Addict
Addict
Posts: 4260
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Pointer to an array inside of a structure

Post by Demivec »

I think it needs to be a slight variation of idle's example:

Code: Select all

Structure MIB_IFROW_STRUCT
  wszName.u[256] ;#MAX_INTERFACE_NAME_LEN];
  dwIndex.l
  dwType.l
  dwMtu.l
  dwSpeed.l
  dwPhysAddrLen.l
  bPhysAddr.a[8] ;MAXLEN_PHYSADDR
  dwAdminStatus.l
  dwOperStatus.l
  dwLastChange.l
  dwInOctets.l
  dwInUcastPkts.l
  dwInNUcastPkts.l
  dwInDiscards.l
  dwInErrors.l
  dwInUnknownProtos.l
  dwOutOctets.l
  dwOutUcastPkts.l
  dwOutNUcastPkts.l
  dwOutDiscards.l
  dwOutErrors.l
  dwOutQLen.l
  dwDescrLen.l
  bDescr.a[256] ;MAXLEN_IFDESCR
EndStructure    

Structure MIB_IFROW
   Row.MIB_IFROW_STRUCT[0]                          ;access the memory with the pattern of the structure, has no size it's just a pattern 
EndStructure

Structure MIB_IFTABLE1
  dwNumEntries.l
  ;followed by a dynamicly sized table.MIB_IFROW 
EndStructure

Define *MIB_IFTABLE.MIB_IFTABLE1, *MIB_IFROW.MIB_IFROW, lSize

lSize =  SizeOf(MIB_IFROW_STRUCT);default size or return from GetIfTable_()
*MIB_IFTABLE.MIB_IFTABLE1 = AllocateMemory(SizeOf(MIB_IFTABLE1) + lSize)
If *MIB_IFTABLE
  *MIB_IFROW.MIB_IFROW = *MIB_IFTABLE + SizeOf(MIB_IFTABLE1)
Else
  ;handle low memory condition
  End
EndIf

lErrors = GetIfTable_(*MIB_IFTABLE, @lSize, 0)
If lErrors = 122 ;ERROR_INSUFFICIENT_BUFFER
  Define *new = ReAllocateMemory(*MIB_IFTABLE, SizeOf(MIB_IFTABLE1) + lSize)
  If *new
    *MIB_IFTABLE = *new
    *MIB_IFROW = *MIB_IFTABLE + SizeOf(MIB_IFTABLE1)
    *new = 0
  EndIf
  lErrors = GetIfTable_(*MIB_IFTABLE, @lSize, 0)
  
  Debug *MIB_IFTABLE\dwNumEntries
  ;display entries
EndIf
User avatar
idle
Always Here
Always Here
Posts: 5836
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Pointer to an array inside of a structure

Post by idle »

Take a look at the msdn example
http://msdn.microsoft.com/en-us/library ... 85%29.aspx

The call to the Get Table will return the required size if the buffer is to small

Sorry I cant test any windows code at the moment my VM's have crapped out from a bad update

Code: Select all

Structure MIB_IFROW_STRUCT
  wszName.u[#MAX_INTERFACE_NAME_LEN];
  dwIndex.l;
  dwType.l; 
  ;...
EndStructure    

Structure MIB_IFROW
   Row.MIB_IFROW_STRUCT[0]                          ;lets you acess the memory by index as a long, structure has no size it's just a pattern 
EndStructure

Structure MIB_IFTABLE1
  dwNumEntries.l
  *table.MIB_IFROW                   
EndStructure

*MIB_IFTABLE.MIB_IFTABLE1 = AllocateMemory(SizeOf(MIB_IFTABLE1)) 

dwSize = SizeOf (MIB_IFTABLE);
If (GetIfTable_(*MIB_IFTABLE, @dwSize, #False) = #ERROR_INSUFFICIENT_BUFFER) 
    FreeMemory(*MIB_IFTABLE);
      *MIB_IFTABLE  =  AllocateMemory(dwsize)) 
       If Not *MIB_IFTABLE 
           MessageRequester("errror","allocating memory needed To CALL GetIfTable");
           ProcedureReturn 1;
      EndIf 
 EndIf 

dwRetVal = GetIfTable( *MIB_IFTABLE, @dwSize, #False)
If dwRetVal = #NO_ERROR    
   For i = 0 To *MIB_IFTABLE \dwNumEntries
      Debug Str(*MIB_IFTABLE\table\Row[i]\dwIndex) 
  Next 
EndIf 
 
Windows 11, Manjaro, Raspberry Pi OS
Image
infratec
Always Here
Always Here
Posts: 7577
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Pointer to an array inside of a structure

Post by infratec »

Hi,

nice try, but:

Code: Select all

Structure MIB_IFROW_STRUCT
  wszName.u[256] ;#MAX_INTERFACE_NAME_LEN];
  dwIndex.l
  dwType.l
  dwMtu.l
  dwSpeed.l
  dwPhysAddrLen.l
  bPhysAddr.a[8] ;MAXLEN_PHYSADDR
  dwAdminStatus.l
  dwOperStatus.l
  dwLastChange.l
  dwInOctets.l
  dwInUcastPkts.l
  dwInNUcastPkts.l
  dwInDiscards.l
  dwInErrors.l
  dwInUnknownProtos.l
  dwOutOctets.l
  dwOutUcastPkts.l
  dwOutNUcastPkts.l
  dwOutDiscards.l
  dwOutErrors.l
  dwOutQLen.l
  dwDescrLen.l
  bDescr.a[256] ;MAXLEN_IFDESCR
EndStructure   

Structure MIB_IFROW
   Row.MIB_IFROW_STRUCT[0]                          ;lets you acess the memory by index as a long, structure has no size it's just a pattern
EndStructure

Structure MIB_IFTABLE1
  dwNumEntries.l
  ;*table.MIB_IFROW
  *table.MIB_IFROW_STRUCT[0]
EndStructure

#NO_ERROR = 0
#ERROR_INSUFFICIENT_BUFFER = 122

Define dwSize.l
Define *MIB_IFTABLE.MIB_IFTABLE1

dwSize = 0
If GetIfTable_(*MIB_IFTABLE, @dwSize, #False) = #ERROR_INSUFFICIENT_BUFFER
  *MIB_IFTABLE  =  AllocateMemory(dwsize)
  If Not *MIB_IFTABLE
    MessageRequester("errror","allocating memory needed To CALL GetIfTable");
    End
  EndIf
EndIf

dwRetVal = GetIfTable_(*MIB_IFTABLE, @dwSize, #False)
If dwRetVal = #NO_ERROR
  Debug "Ptr to the whole structure: " + Hex(*MIB_IFTABLE)
  Debug "Ptr to the first table entry INSIDE the structure (should be the value from before + 4) " + Hex(*MIB_IFTABLE\table[0])
  
  *MIB_IFTABLE\table[0] = *MIB_IFTABLE + 4
  Debug "Manually set to: " + Hex(*MIB_IFTABLE\table[0])
  
  ShowMemoryViewer(*MIB_IFTABLE, 100)
  
  For i = 0 To *MIB_IFTABLE \dwNumEntries - 1
    Debug "Table Ptr for entry " + Str(i) + " is " + Hex(*MIB_IFTABLE\table[i])
    Debug *MIB_IFTABLE\table[i]\dwDescrLen
    Debug PeekS(*MIB_IFTABLE\table[i]\bDescr, -1, #PB_Ascii)
  Next
EndIf 
The ptr to the ROW points not directly after the entry of wdNumEntries :!:
And even if I set it manually to this address, I get garbage as result,
because than the new value is written at this place :!:
This is very strange, because before it was pointing to something.
So the first 4 bytes of the row are overwritten.
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Pointer to an array inside of a structure

Post by Danilo »

Guys, 'table' is not a pointer: ;)

Code: Select all

Structure MIB_IFROW
    wszName.u[256] ;#MAX_INTERFACE_NAME_LEN];
    dwIndex.l
    dwType.l
    dwMtu.l
    dwSpeed.l
    dwPhysAddrLen.l
    bPhysAddr.a[8] ;MAXLEN_PHYSADDR
    dwAdminStatus.l
    dwOperStatus.l
    dwLastChange.l
    dwInOctets.l
    dwInUcastPkts.l
    dwInNUcastPkts.l
    dwInDiscards.l
    dwInErrors.l
    dwInUnknownProtos.l
    dwOutOctets.l
    dwOutUcastPkts.l
    dwOutNUcastPkts.l
    dwOutDiscards.l
    dwOutErrors.l
    dwOutQLen.l
    dwDescrLen.l
    bDescr.a[256] ;MAXLEN_IFDESCR
EndStructure   

Structure MIB_IFTABLE
    dwNumEntries.l
    table.MIB_IFROW[0]
EndStructure

#NO_ERROR = 0
#ERROR_INSUFFICIENT_BUFFER = 122

Define dwSize.l
Define *MIB_IFTABLE.MIB_IFTABLE

dwSize = 0
If GetIfTable_(0, @dwSize, #False) = #ERROR_INSUFFICIENT_BUFFER
    *MIB_IFTABLE  =  AllocateMemory(dwsize)
    If Not *MIB_IFTABLE
        MessageRequester("errror","allocating memory needed To CALL GetIfTable");
        End
    EndIf
Else
    End
EndIf

dwRetVal = GetIfTable_(*MIB_IFTABLE, @dwSize, #True)
If dwRetVal = #NO_ERROR
    Debug "Number of entries: "+*MIB_IFTABLE\dwNumEntries
    
    If *MIB_IFTABLE\dwNumEntries > 0
        For i = 0 To *MIB_IFTABLE \dwNumEntries - 1
            Debug "--------------------"
            Debug "Index: "         + Str(   *MIB_IFTABLE\table[i]\dwIndex)
            Debug "Interface name: "+ PeekS(@*MIB_IFTABLE\table[i]\wszName[0], 256, #PB_Unicode)
            Debug "Description: "   + PeekS(@*MIB_IFTABLE\table[i]\bDescr[0] , *MIB_IFTABLE\table[i]\dwDescrLen, #PB_Ascii)
            Select *MIB_IFTABLE\table[i]\dwType
                    ;Case #IF_TYPE_OTHER
            EndSelect
            Debug "Mtu: "           + Str(   *MIB_IFTABLE\table[i]\dwMtu)
            Debug "Speed: "         + Str(   *MIB_IFTABLE\table[i]\dwSpeed)
            ; ...
        Next
    EndIf
    
EndIf
infratec
Always Here
Always Here
Posts: 7577
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Pointer to an array inside of a structure

Post by infratec »

And the winner is...

Danilo

I had this alreday, but than I had an other mistake in my code.

Thank's to all who helped to solve my small problem.

Bernd
Post Reply