About Monkey 2 › Forums › Monkey 2 Programming Help › Function variable pointer
This topic contains 11 replies, has 6 voices, and was last updated by 
 Mark Sibly
 2 years, 1 month ago.
- 
		AuthorPosts
 - 
		
			
				
February 22, 2017 at 11:49 pm #7257
How do I pass a variable to a function as a pointer?
If I pass an image to my function and load an image into the image variable, it’s not applied outside of that function.If I define the function with image:Image Ptr as the perameter and pass Varptr myImage to it, it seems to work.
But accessing the image via either just image=Image.Load or image[0]=Image.Load causes a compile error.Monkey123error: cannot convert 'bbGCVar<t_mojo_graphics_Image>*' to 't_mojo_graphics_Image**' for argument '1' to 'bbBool g_gw2map_DownloadTile(t_mojo_graphics_Image**, bbInt, bbInt, bbInt, bbInt, bbInt)'g_gw2map_DownloadTile(&f3.l_c->m_preview,l_continent,bbInt(0),bbInt(0),bbInt(0),bbInt(0));February 23, 2017 at 5:03 pm #7266Images are reference based so there is no need to use pointer… (or you re doing some specific external stuffs) It is supposed to passed by reference and any modifications should be kept.
Did you Flushed the drawing commands: MyCanvas.Flush()? Note that flushing might slow down you process.
It’s easier to help with the code..
here is an example of a function drawing to an image with modification by reference.
[/crayon]Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354[crayon-5cba947fedeff124919042 inline="true" ]Namespace myapp#Import "<std>"#Import "<mojo>"Using std..Using mojo..Class MyWindow Extends WindowField im:ImageMethod New( title:String="Simple mojo app",width:Int=640,height:Int=480,flags:WindowFlags=Null )Super.New( title,width,height,flags )im=New Image (400,400)EndMethod OnRender( canvas:Canvas ) OverrideApp.RequestRender()DrawThings(im)canvas.DrawImage (im,50,50)EndEndFunction Main()New AppInstanceNew MyWindowApp.Run()EndFunction DrawThings(img:Image)Local canv:Canvascanv=New Canvas (img)canv.Clear (Color.White)canv.Color=Color.Blackcanv.DrawText( "Hello World!",10,10 )canv.DrawPoint (3,3)canv.Flush()EndFebruary 24, 2017 at 3:18 am #7270Your example doesn’t show
.”…and load an image…”
Which is the problem.
Here’s an example showing that it just doesn’t work.
https://dl.dropboxusercontent.com/u/2842751/image_test.zipFebruary 24, 2017 at 6:39 am #7271> Here’s an example showing that it just doesn’t work.
> https://dl.dropboxusercontent.com/u/2842751/image_test.zipMark should take a look at your example.
Here an ugly test using casting to ‘Void Ptr’:
Monkey12345678910111213141516171819202122232425262728293031323334353637383940#Import "<std>"#Import "<mojo>"Using std..Using mojo..#Import "assets/"Class MyWindow Extends WindowField myImage:ImageMethod New(title:String="Simple mojo app",width:Int=640,height:Int=480,flags:WindowFlags=Null)Super.New(title,width,height,flags)MyImageLoadingFunc2( Varptr myImage )EndMethod OnRender( canvas:Canvas ) OverrideApp.RequestRender()If myImage Thencanvas.DrawImage(myImage,50,50)ElsePrint "Nope, no image"EndifEndEndFunction Main()New AppInstanceNew MyWindowApp.Run()EndFunction MyImageLoadingFunc(imagePtr:Void Ptr)Local im:Image Ptr = Cast<Image Ptr>(imagePtr) ' with temporary variable for castingim[0] = Image.Load("asset::test.jpg")EndFunction MyImageLoadingFunc2(imagePtr:Void Ptr)Cast<Image Ptr>(imagePtr)[0] = Image.Load("asset::test.jpg") ' without temporary variableEndWorks, but casting to void ptr is not typesafe.
February 24, 2017 at 8:18 am #7272@danilo Line 6 #import “assets/”
I’ve found that it is best to reference each asset individually and not import using a wildcard.
Although it work. I found that on windows it would copy assets into the assets folder and also the contents folder. osx worked fine
When referencing individual files, the asset all appeared correctly in the assets folder on compile
February 24, 2017 at 11:10 am #7274My example finished with a crash after a few time… Problem(?) with canvas that I reported.
The Image objects are extending resource and resource are not GCed, and images can be created only after “New Appinstance”.
The error message shows that it’s confused with some GCed object and some non GCed object. It converted the image to some GCed object but should not have done that.
And your simple Function should just work. I tried with a method but it’s still the same problem!In my opinion you found 2 bugs! and I found one with my un-usefull example! Nice shot!
EDIT:reported all 3 supposed bugs on github.
March 1, 2017 at 12:46 pm #7350Mark has answered the issue and said function params are not actually passed by reference even if classes are reference based. (the problem of image pointers is something else):
This is expected behaviour – functions parameters are not passed ‘by reference’ so when you assign to ‘img’ inside ‘MyImageLoading’ you are only assigning to a local variable which disappears when the function returns.
I still don’t understand the exact behaviour of my above example though, and why it works..
But this example shows a bit of reference based classes behavior in mx2:
And if you use a global foo class for pointers you’ll end with the same kind of errors we have with image pointers.[/crayon]Monkey1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980[crayon-5cba948006933064539762 inline="true" ]Namespace myapp#Import "<std>"Using std..Global fg:fooClass fooField str:StringMethod New()str="default"EndEndFunction Main()Local f:=New foo()Local f2:=New foo()f2.str="f2"Print f.strmodify(f)Print f.str + " >you might think it's passed by reference because the modification has been recorded but.."modify2(f)Print f.str + " >it was assigned to a modified local and was not modified after return, if really by reference it should not point to the old one anymore.."Print "-------"modifyr(f,f2)Print f.str+" >this where you see it's not actually passed by reference!"Print f2.str+" >this where you see it's not actually passed by reference!"f=f2Print f.str+ " >here it worked because the objects references where not passed to a function"Print f2.str+ " >here it worked because the objects references where not passed to a function"f2.str="modd"Print f.str+ " >they have the same memory now!"Print f2.str + " >they have the same memory now!"f=New foo()f2=New foo()f2.str="newf2"Print "---"Print f.str + " >they are two new diffrent ones now"Print f2.str + " >they are two new diffrent ones now"Print "-"modifyp(Varptr f,Varptr f2)Print f.str + " >Using pointer worked for passing by reference"Print f2.str + " >Using pointer worked for passing by reference"f2.str="last mod"Print f.strPrint f2.strEndFunction modify(f:foo)f.str="mod"EndFunction modify2(f:foo)Local fl:=New foo()fl.str="mod2"f=flEndFunction modifyr(fr:foo,f2r:foo)fr=f2rEndFunction modifyp(fp:foo ptr,f2p:foo ptr)f2p->str="modp"fp[0]=f2p[0]EndMarch 1, 2017 at 3:55 pm #7353Well that’s kinda how I expected images to work.
But I figured that there might be some way to change that, either by passing it as Ptr and accessing it via [0] or something, but that just throws an error.
I ended up passing the loaded image from inside the function as a return value and via some lambda functions I managed to get it working.March 1, 2017 at 11:12 pm #7354Mx2 doesn’t have ‘var’ params so you can’t pass a ‘variable’ to a function.
An array can be used here though – this is preferred to Varptr as it will prevent the object potentially being GC prematurely:
Monkey123456789101112131415Function Blah()Local ref:=New Image[1]MyLoadImage( ref )Local img:=ref[0]EndFunction MyLoadImage( ref:Image[] )ref[0]=LoadImage...EndSomething like ‘Out’ or Var’ params will likely happen at some point, not sure when.
March 1, 2017 at 11:41 pm #7355Mx2 doesn’t have ‘var’ params so you can’t pass a ‘variable’ to a function.
What’s the logic behind this decision?
March 2, 2017 at 6:31 am #7356> Something like ‘Out’ or Var’ params will likely happen at some point, not sure when.
+1 for ‘Out’ params.
March 5, 2017 at 8:40 pm #7383> What’s the logic behind this decision?
Becasue it’s hard to do and I haven’t found a need for it myself or had requests for it yet!
 - 
		AuthorPosts
 
You must be logged in to reply to this topic.