Gathering Data (with CreateBank) from a C struct

Blitz3D Forums/Blitz3D Userlibs/Gathering Data (with CreateBank) from a C struct

Chi3f Stadi(Posted 2006) [#1]
Hello

I'm stuck in a problem using a .dll which contains structs pointing to other structs.

The struct looks like:
struct pcap_if {
	struct pcap_if *Next;
	char *name;		/* name to hand to pcap_open_live()" */
	char *description;	/* textual description of interface, or NULL */
	struct pcap_addr *addresses;
	bpf_u_int32 flags;	/* PCAP_IF_ interface flags */
};


if i access the banks first integer (PeekInt) it returns an address, but after the first 4 bytes the bank is empty.

Can you help me accessing this kind of struct. Is it possible ?


Dreamora(Posted 2006) [#2]
I think the problems are the char pointers

You need to replace them with fixed length char arrays so blitz can handle the bank as a continous memory block.


Kev(Posted 2006) [#3]
could you not create a bank to hold the data to be obtained from the struct's address you get when using peekint(), then use RtlCopyMemory() to grab the data from the address.

*edit. i think i misunderstood what your asking.

kev


Chi3f Stadi(Posted 2006) [#4]
hmmm . may that is a solution, but RtlCopyMemory() is not a BB3D command.

Unfortunately, this is an 3rd party .dll. May it is easier to write an additional dll for Blitz3D to use those functions ...


Kev(Posted 2006) [#5]
you would need to use RtlMoveMemory() the function call can be found in kernel32.dll


jfk EO-11110(Posted 2006) [#6]
I had a similar problem where avifil32.dll requested for a list of pointers to structs. (basicly it was only one pointer, but the dll wanted the adress of the adress, and not simply the adress of it, however). First I tried to poke pointers to further banks, ready for retrieving struct data into the bank supposed to contain a list of pointers. Then, and that was the problem, something didn't allow the DLL to write the data to the banks that were not mentioned in the dll function call, I think. The solution was then: create a bank that is big enough to hold all struct data plus the pointers, poke some pointers to the "header" of the bank, pointing to the "body" of the same bank.

Uh, this is now confusing even myself o_O - well basicly the bank contains some adresses that are pointing to the bank itself, plus certain offsets. This way Blitz seems to allow the retrieving of the structs sent by the dll.

NOTE:
The (handle of a bank plus 4) is the adress of a pointer to the banks data segment.


So when we assume that the struct is 256 bytes long and there are max 16 structs returned, you could:
rtl_bank=createbank(4) ; bank to retrieve adress of bank

bank=createbank((4*16)+(256*16)) ; bank for the structs etc

RTLMoveMemory(rtl_bank,bank+4) ; determine banks real adress

adr=peekint(rtl_bank,0)

for i=0 to 16-1
 pokeint bank,i*4,adr+(4*16)+(i*256) ; poke pointers for structs
next


See the "How to hack certain properties" (or similar) in the Blitz3D Tutorial section about how to use RTLMoveMemory.


Chi3f Stadi(Posted 2006) [#7]
Thank you. This could really solve the problem. I haven't tried it.

RTL reminds me of a german TV channel ... hehe

EDIT:
Great it really works that way. Here is a short snippet how i use this kernel32 RTL function ... thanks jfk

Function GetChars$(memaddr)
	;interates through memory until it finds a NULL str
	;memaddr is the starting point
	;returns the strin
	Local lChar$,lRetString$
	Local i% = 0
	lCharBank = CreateBank(4)

	Repeat
		RTLMoveMemory2(lCharBank,memaddr+i,1)
	
		;Save char in lChar
		lChar = Chr$(PeekByte(lCharBank,0))

		;test for NULL string
		If (Asc(lChar) <> 0) Then
			lRetString = lRetString + lChar
			i = i + 1
		Else
			Exit
		End If
	Forever

	Return lRetString

End Function