PDA

View Full Version : Personal Help on ASM



ErosOlmi
09-03-2010, 16:02
I need some help on PowerBasic inline ASM side.
I hope Charles or others can help me on this.

I discovered a problem when thinBasic calls an external function returning a dynamic BSTR string. So something like MyFun(...) AS STRING.
When thinBasic calls those kind of functions it does something like (PowerBasic code):

'...
!Xor eax, eax
!Call hProc
!mov RetVal, eax
'...
where hProc is the code pointer to MyFun and RetVal is a DWord
RetVal is the pointer to the first byte of dynamic string data (STRPTR)

I would like instead to get the VARPTR to dynamic string or order to be able to free it otherwise memory used to return function value remains allocated.

How can I do in PowerBasic inline ASM?

Thanks a lot
Eros

Charles Pegge
09-03-2010, 17:01
Hi Eros,

The strptr returned in the eax register is all you need to directly manage the BSTR. You pass this value to SysFreeString to release the string. Thus:

dim bst as dword
call dword SomeBStringFunction using ..(...) to bst

....

SysFreeString bst

Normally the string descriptor (accessed by varptr) is created by PB. Did you want to manage the returned string directly in thinCore?

Charles

ErosOlmi
09-03-2010, 17:09
Charles,

I'm already doing that but the BSTR is not released.


pStr = RetVal '---This is the above return values
If pStr Then
sLen = CVL(PEEK$(pStr - 4&, 4&)) '---Get the length of the string
If sLen Then
lResultStr = peek$(pStr, sLen ) '---Get the string
SysFreeString(pStr) '---Here it is not free
END IF
END IF

D.J.Peters
09-03-2010, 17:49
why you mean it isn't free after SysFreeString(pStr) ?

it can point to the old string space so you think it isn't deallocated
it's good practice to set deallocated pointers to NULL,

(sorry my powerbasic time are long a go i wrote the GDK for Kirschbaum GmbH in the begin of the 90th)

Joshy

Charles Pegge
09-03-2010, 18:00
Yes, like a zombie the dead string may appear to be live :shock: and persist in system memory. But the space it occupies will eventually be recycled by the OS.

ErosOlmi
09-03-2010, 18:05
I'm not sure it is working and it is just a OS recycling.

If with return pointer I'm able to get the dynamic string DATA, it means it is a data pointer and not a BSTR pointer.
With a data pointer I cannot free a BSTR, I need to BSTR pointer.

mubling ...

Charles Pegge
09-03-2010, 18:43
A BSTR is certainly a pointer. It is passed to SysFreeString Byval. So your pointer variable remains unaltered after this call. You can set this variable to zero so the dead BSTR can't be used again by accident.

Do you see any problems with your Bstrings - like a build-up of memory?

Charles

ErosOlmi
09-03-2010, 22:15
Do you see any problems with your Bstrings - like a build-up of memory?


Yes, that's why I asked.
BSTR is a 2 pointers structure
A pointer to a DWORD (VARPTR) that points to the allocated dynamic string (STPTR)

To be able to free the BSTR I need the VARPTR and not the STRPTR
With the STRPTR I can access the string data and get string len (STRPTR - 4 bytes) but I cannot free the memory
With the VARPTR (pointer to a pointer that points to dynamic data) I can free the BSTR

Of course if I'm not wrong.

http://oreilly.com/catalog/win32api/chapter/ch06.html#20265
http://oreilly.com/catalog/win32api/chapter/api_0605.gif

José Roca
10-03-2010, 00:24
I guess you're using a declare such DECLARE SUB SysFreeString LIB "OLEAUT32.DLL" ALIAS "SysFreeString" (bstr AS ANY). Therefore, use SysFreeString(BYVAL pStr).

Charles Pegge
10-03-2010, 00:45
Hi Eros,

A BSTR has only a simple pointer. (strptr) with one level of indirection

PB uses a dynamic string descriptor. the first DWORD of this descriptor is where it stores the BSTR. Hence you have this double pointering thing. But the OLE string functions themselves do not know anything about this.


Here is the definitive guide to OLE Bstrings:

http://msdn.microsoft.com/en-us/library/ms221105.aspx

Also:

Rules for Freeing BSTRs in OLE Automation:

http://support.microsoft.com/kb/108934


As well as PB, FB also uses a double pointering scheme for its dynamic strings but it does not use the OLE string functions. Oxygen uses double pointering as well. The main advantage of doing this in compiled systems is easy garbage collection. At the end of a function you have a single list of BSTRs to free up, and you don't have to deal with individual variables.


Charles


PS:
@José: Yes that looks like an easy trap to fall into.



Therefore, use SysFreeString(BYVAL pStr).

ErosOlmi
14-03-2010, 13:47
Thank you very very much to all.

José, you got it 100%
I'm using declare from official WIN32API.INC that uses ANY, so I need to pass the pointer as BYVAL otherwise it computers the pointer to my pointer.

Thanks again.
Eros