glib and ptr ptr variables

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

glib and ptr ptr variables

Post by Iczer »

what would be correct way to write code for function g_file_get_contents() https://docs.gtk.org/glib/func.file_get_contents.html
This:

Code: Select all

Dim As ZString Ptr psFile_Content

If g_file_test(psFile_FullFilePath, G_FILE_TEST_EXISTS) Then

	Dim As gchar ptr ptr gsFile_Content
	Dim As gsize Ptr giFile_ContentLength

	If g_file_get_contents(psFile_FullFilePath, gsFile_Content, giFile_ContentLength, NULL) Then
		
		psFile_Content = Callocate(*giFile_ContentLength + 1,1)
		
		memcpy(psFile_Content,*gsFile_Content,*giFile_ContentLength)
		
		g_free(gsFile_Content)
	EndIf
EndIf
Or this:

Code: Select all

Dim As ZString Ptr psFile_Content

If g_file_test(psFile_FullFilePath, G_FILE_TEST_EXISTS) Then

	Dim As ZString Ptr gsFile_Content
	Dim As Long iFile_ContentLength

	If g_file_get_contents(psFile_FullFilePath, @gsFile_Content, @iFile_ContentLength, NULL) Then
		
		psFile_Content = Callocate(iFile_ContentLength + 1,1)
		
		memcpy(psFile_Content, gsFile_Content, iFile_ContentLength)
		
		g_free(gsFile_Content)
	EndIf
EndIf
caseih
Posts: 1971
Joined: Feb 26, 2007 5:32

Re: glib and ptr ptr variables

Post by caseih »

All you have to do is declare a pointer variable, and then pass a pointer to that pointer variable. This is because this function allocates memory for you and wants to give you a pointer to that memory. So it's actually going to alter the "destination" of the pointer you DIMmed. In other words it's going to set your pointer to point to the allocated memory (equivalent of altering a variable passed byref). Hope that makes sense. If this were a native FB function, you'd probably make that parameter a byref ptr. But in C, the only way to do that is by passing a pointer, hence the ptr ptr.

It would look something like this:

Code: Select all

Dim as Zstring Ptr psFile_Content

if g_file_get_contents(psFile_FullFilePath, @psFile_Content, giFile_ContentLength, NULL) then
    'psFile_Content now points to the allocated memory containing the file's contents
    ....
You will have to fall g_free() on psfile_Content later.
Iczer
Posts: 80
Joined: Jul 04, 2017 18:09

Re: glib and ptr ptr variables

Post by Iczer »

Thanks!
TJF
Posts: 3758
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Re: glib and ptr ptr variables

Post by TJF »

Hi Iczer, some hints:

1) Don't mix FreeBASIC and GLib types. This complicates bug tracking. Instead of ZSTRING use the original gchar type.

2) DIM the variable of that type you need in your code (instead of the type the API requires)

Code: Select all

Dim As gchar Ptr gsFile_Content
Dim As gsize giFile_ContentLength
and add the second pointer in the parameter list

Code: Select all

g_file_get_contents(psFile_FullFilePath, @gsFile_Content, @giFile_ContentLength, NULL)
The @ character indicates that it is a return parameter.

3) There's no need to copy the buffer. Instead just keep the GLib buffer and - when done - g_free(gsFile_Content) instead of DEALLOCATE(psFile_Content).

4) The function g_file_get_contents() does good error checking. You can omit the prepended g_file_test() call, by no costs but better information for the user.

5) Short variable names are more easy to read (and less typing).

So I'd code

Code: Select all

DIM AS  gchar PTR buff
DIM AS  gsize     size
DIM AS GError PTR errr

IF FALSE = g_file_get_contents(psFile_FullFilePath, @buff, @size, @errr) THEN ' there's a problem
  PRINT errr->Message ' informing user
  g_error_free(errr) ' note: no g_free(buff) here since GLib didn't allocate memory (buff = NULL, size = 0)
  ' further error handling ..., ie 
  END(1)
ENDIF
	
' buffer OK, do something with it ...
	
g_free(buff)
Post Reply