I use this code to get the interface of a ClassLibrary and I have a warning during compiling time.. I'd like to know why, so I can fix it and learn how to proceed..
Here is the code I use:
struct ClassLibrary *ListBrowserBase = NULL; Class *ListBrowserClass; struct ListBrowserIFace *IListBrowser = NULL; ListBrowserBase = (struct ClassLibrary *)IIntuition->OpenClass("gadgets/listbrowser.gadget", 52, &ListBrowserClass); if(ListBrowserBase == NULL){ IDOS->Printf("Impossibile ottenere ListBrowserBase!\n"); }else{ IDOS->Printf("ListBrowserBase ottenuto correttamente!\n"); } IListBrowser = (struct ListBrowserIFace *)IExec->GetInterface(ListBrowserBase, "main", 1, NULL); if(IListBrowser == NULL){ IDOS->Printf("Impossibile ottenere IListBrowser\n"); }else{ IDOS->Printf("IListBrowser ottenuto correttamente!\n"); }
that's the error:
esempio.c: In function 'main':
esempio.c:109: warning: passing argument 2 of 'IExec->GetInterface' from incompatible pointer type
What am I doing wrong?
@Nube
GetInterface() takes a struct Library pointer as its first argument, so try type-casting your class library pointer as follows:
IListBrowser = (struct ListBrowserIFace *) IExec->GetInterface((struct Library *) ListBrowserBase, "main", 1, NULL);
AmigaOne X5000-020 / 2GB RAM / Sapphire Pulse Radeon RX 560 / AmigaOS 4.1 Final Edition Update 2
Thanks a lot!, it works!, no more warning :-)
Just to add. I used to get a few of these some years back and they can be confusing if you don't understand what's going on. You will notice it said argument 2 but the problem was with ListBrowserBase which is the first argument you passed. Huh? :-)
The reason for this is the way calling functions or methods are implemented in an Interface. See every time you call a method from an Interface, just like when calling a 68K library function, it needs to have the base pointer as well. Which uses some compiler magic to pass the Interface as argument 1.
Now this is all hidden of course as if you had to manually pass the Interface yourself the code would look quite obtuse. And would defeat the purpose of being object oriented.
This explains how passing argument 1 to an Interface method ends up as argument 2 in the actual function call. :-)
Thanks for the addendum, indeed you are right, the argument passed is the first and not the second.. So, to better understand what you are saying, I have to cast the first argument for an inner mechanism of AmigaOS4 interfaces and methods? is it so? for me, at the moment, it is ok because I am moving my first steps into the developing for AmigaOS4 so I do not pretend to fully understand everything at the very beginning of my journey but if you could clarify the concept this would help me to better understand this.. :-)
With the interface method the actual interface is argument one. Take this as an example:
IDOS->Lock( file, SHARED_LOCK )
This would actually translate to:
Lock( struct DOSIFace *Self, CONST_STRPTR name, LONG type )
Therefore, the name passed in is actually argument 2 even though it appears to be argument 1 in the first example.
Simon
Thanks for the reply and the explanation, much clear now :-)
Hello again.
Yeah Simon pretty much explained it. So you don't have to cast anything or think about since it's all automatic in the APICALL. Only to keep it mind when you get errors like above.
It's like on 68K where the A6 register has to hold the library base to call the function off. You don't see it when coding in C. Even if it is the last register or argument in this case it functions the same as an OS4 library call. :-)
Thanks for all the informations, really appreciated :)