return data from function as UDT array pointer

New to FreeBASIC? Post your questions here.
Post Reply
Iczer
Posts: 99
Joined: Jul 04, 2017 18:09

return data from function as UDT array pointer

Post by Iczer »

i need to return from function pointer to UDT array of unknown beforehand size. i tried to do it like this (example - no errors from compiler):

Code: Select all

#Define unicode

#Pragma Once
#include Once "windows.bi"
#include Once "win/commctrl.bi"
#include once "glib.bi"
' =============================================================
Const As Byte idTVItemIcon_Default = 7
Const As COLORREF cCOLOUR_DefaultBlack = &H000000
' =============================================================
Type tagInitData
	
	path1 As WString * 1024	=	""
	path2 As WString * 1024	=	""
	
	alert  As Boolean			= TRUE

	max  As Integer			= 0
	
End Type
' =============================================================
Type tagReturnData
	
	iID				As ULong				= 0
	name				As WString * 256	=	""
	path				As WString * 1024	=	""
	alert				As Boolean			= TRUE
	TimeString		As ZString * 256	=	""
	TimeEPOCH		As LongInt			= 0
	TimeGDateTime	As GDateTime Ptr

	max				As Integer			= 0
	stats				As ZString * 64	= ""
	
	TV_itemHandle	As HTREEITEM		= 0
	TV_itemIcon		As Byte				= idTVItemIcon_Default
	Color				As COLORREF			= cCOLOUR_DefaultBlack
	
End Type
' =============================================================
Dim Shared As tagReturnData aDataGlobal()

' =============================================================
Extern "Windows-MS"
' =============================================================


' =============================================================
Public Function Init(tInitData As tagInitData, ByRef iCount As Integer, ByRef tReturnData As tagReturnData Ptr) As Integer Export
	
	' ------------------------------------------------------------
	' 
	' ...
	'
	' ------------------------------------------------------------
	iCount = UBound(aDataGlobal)
	tReturnData = New tagReturnData[iCount]
	
	Print " -------> iCount = ";iCount
	
	For i As Integer = 1 To iCount
		
		Print " --> iID = ";i
		' .........................................................
		tReturnData[i-1].iID					= aDataGlobal(i).iID
		tReturnData[i-1].name				= aDataGlobal(i).name
		tReturnData[i-1].path				= aDataGlobal(i).path
		tReturnData[i-1].alert				= aDataGlobal(i).alert
		tReturnData[i-1].TimeString		= aDataGlobal(i).TimeString
		tReturnData[i-1].TimeEPOCH			= aDataGlobal(i).TimeEPOCH
		tReturnData[i-1].TimeGDateTime	= aDataGlobal(i).TimeGDateTime

		tReturnData[i-1].max					= aDataGlobal(i).max
		tReturnData[i-1].stats				= aDataGlobal(i).stats

		tReturnData[i-1].TV_itemHandle	= aDataGlobal(i).TV_itemHandle
		tReturnData[i-1].TV_itemIcon		= aDataGlobal(i).TV_itemIcon
		tReturnData[i-1].Color				= aDataGlobal(i).Color
		' .........................................................
		
		'Print "tReturnData[i-1].name = ";tReturnData[i-1].name

	Next i
	' ------------------------------------------------------------
	Return 0
End Function
' =============================================================
End Extern
' =============================================================
but it return normally only first element, on second and others "tReturnData[i-1].iID" become zero and WStrings get crippled/blanked. other datatypes ok.
If i uncomment "Print "tReturnData[i-1].name = ";tReturnData[i-1].name" - it wont print anything and after it "Print " --> iID = ";i" also wont work.

it seems something wrong, but cannot find it...
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: return data from function as UDT array pointer

Post by fxm »

1)
How the array aDataGlobal is sized (before calling the procedure init())?

2)
Somewhere, after each call of init(), you must free the allocated memory (by New[]):

Code: Select all

Delete[] tReturnData
3)
Compile with option -exx.
Run the compiled program from a command window for example (or from an IDE allowing to visualize the runtime error messages).
See if a runtime error message is displayed.
Iczer
Posts: 99
Joined: Jul 04, 2017 18:09

Re: return data from function as UDT array pointer

Post by Iczer »

array is sized like this:

Code: Select all

Dim As ULong iCount
Dim aData() As tagReturnData

ReDim aData(1 To iCount) As tagReturnData
For i As Integer = 1 To UBound(aData)

	aData(i).iID				= i
	aData(i).name				= 
	aData(i).path				= 
	aData(i).alert				= 
	aData(i).TimeString		= 
	aData(i).TimeEPOCH		= 
	aData(i).TimeGDateTime	= 

	aData(i).max				= 
	aData(i).stats				= 
	
	aData(i).TV_itemHandle	= 
	aData(i).TV_itemIcon		= 
	aData(i).Color				= 

Next i

ReDim ReDim aDataGlobal(1 To UBound(aData)) As tagReturnData

For i As Integer = 1 To UBound(aData)
	aDataGlobal(i) = aData(i)
Next i
i'm run Delete[] tReturnData on before exit in close() function

i'm compiling in FbEdit with option fbc -asm intel -s gui -dll -export -exx

and run function from dll from SciTE4AutoIt3, but no additional strings appear in console

i changed "Type tagReturnData" to "Type tagReturnData Field = 4" and some parts of previously missing wstrings appeared, but as number of array element increase, those parts get smaller and in the end disapear.
i think issue have something to do with structure definition on caller side, but why not working

Code: Select all

Print "tReturnData[i-1].name = ";tReturnData[i-1].name
from inside function?
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: return data from function as UDT array pointer

Post by fxm »

I propose you to just simplify 2 lines to check that a new local array is not created instead of resize an already defined array:
.....
ReDim aData(1 To iCount) As tagReturnData
.....
ReDim aDataGlobal(1 To UBound(aData)) As tagReturnData
.....
Iczer
Posts: 99
Joined: Jul 04, 2017 18:09

Re: return data from function as UDT array pointer

Post by Iczer »

i simplified those lines and there a was no errors on compile or on console after function run
if i make print like this

Code: Select all

Print "tReturnData[i-1].name = ";Str(tReturnData[i-1].name)
then print on wstring working ok - it seems SciTE console don't like raw UTF-16

as original issue - i got it fixed on caller side structure definition by wrapping not only all array, but also each element of array in"struc;...;endstruc" so structure alignment got fixed
Iczer
Posts: 99
Joined: Jul 04, 2017 18:09

Re: return data from function as UDT array pointer

Post by Iczer »

also - about use New/Delete operators - if i pass data to thread like this:

Code: Select all

Dim pDataParse Ptr As tagDataParse
pDataParse = New tagDataParse
'...............................................................................
pDataParse->... 
pDataParse->... 
pDataParse->... 
'...............................................................................

'...............................................................................
RetVal = g_thread_pool_push (UpdateThreadPool,pDataParse,@ErrorValue)
'...............................................................................
when i should/can call Delete pDataParse? Can i do it immediatly after passing data to thread, or after thread end i's work?
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: return data from function as UDT array pointer

Post by fxm »

As long as the thread accesses to data created by the "New" operator, you cannot free the allocated memory by calling the "Delete" operator.
Iczer
Posts: 99
Joined: Jul 04, 2017 18:09

Re: return data from function as UDT array pointer

Post by Iczer »

Thanks!
Post Reply