As the title says, i have this error and I don't know what is wrong, it is more a c error than an amiga error but i don't know how to fix it.. here is my code. I am trying to create a simple window with a two column listbrowser gadget.. May you help me please?
/*****************************************************/ /* */ /* PER COMPILARE: */ /* */ /* gcc -o lb list_browser.c */ /* */ /*****************************************************/ #include <stdio.h> // standard inputoutput c library #include <proto/exec.h> // exec library #include <proto/dos.h> // dos library #include <proto/intuition.h> // intuition library #include <intuition/gui.h> #include <classes/window.h> // Window class per oop boopsi window #include <gadgets/button.h> // Button gadget per bottoni finestra #include <gadgets/layout.h> // Layout gadget per disposizione oggetti in finestra #include <gadgets/listbrowser.h> // ListBrowser gadget per visualizzare elenchi liste struct ClassLibrary *WindowBase; // WindowBase pointer per accedere all'interfaccia della windows class Class *WindowClass; // Window class pointer per accedere alle funzioni della window class struct ClassLibrary *LayoutBase; // LayoutBase pointer per accedere alla layoutbase Class *LayoutClass; // LayoutClass pointer per accedere alle funzioni della LayoutClass struct ClassLibrary *ButtonBase; // ButtonBase pointer per accedere alla ButtonClass interface Class *ButtonClass; // ButtonClass pointer per accedere alle funzioni della Button Class struct ClassLibrary *ListBrowserBase; // ListBrowserBase Class *ListBrowserClass; // ListBrowserClass struct ListBrowserIFace *IListBrowser = NULL; struct Library *IntuitionBase = NULL; // IntuitionBase pointer per accedere alla libreria Intuition struct IntuitionIFace *IIntuition = NULL; // IIntuition pointer per accedere alle funzioni della libreria Intuition tramite la sua interfaccia struct List listbrowser_list; struct ColumnInfo *column_info = NULL; enum{ OID_FINESTRA, OID_LAYOUT_1, OID_LAYOUT_2, OID_LISTBROWSER, OID_LAST }; Object *objects[OID_LAST]; // indichiamo la grandezza del nostro puntatore di tipo Object static const char USED minstack[]="$STACK:80000"; // indichiamo il minimo di memoria richiesta per eseguire il nostro programma /* ELEMENTI LISTBROWSER: */ uint32 tagdatas[2]; int32 tags[] = { GUIA_ScreenDragging, GUIA_OffScreenDragging }; STRPTR list_strings[] = { "GUIA_ScreenDragging", "GUIA_OffScreenDragging", NULL }; BOOL make_browserlist(struct List *, char **, uint32 *); /* FINE ELEMENTI LISTBROWSER */ int main(){ IntuitionBase = IExec->OpenLibrary("intuition.library", 52); if(IntuitionBase == NULL){ IDOS->Printf("Impossibile ottenere IntuitionBase pointer, impossibile aprire la libreria\n"); }else{ IDOS->Printf("\nIntuitionBase pointer ottenuto, libreria aperta correttamente\n"); } IIntuition = (struct IntuitionIFace *)IExec->GetInterface(IntuitionBase,"main",1,NULL); if(IIntuition == NULL){ IDOS->Printf("Impossibile ottenere Intuition Interface\n"); return(0); }else{ IDOS->Printf("Intuition Interface ottenuta correttamente\n"); } WindowBase = IIntuition->OpenClass("window.class", 52, &WindowClass); if(WindowBase == NULL){ IDOS->Printf("impossibile ottenere WindowBase, impossibile aprire la Window class\n"); return(0); }else{ IDOS->Printf("WindowBase ottenuta correttamente, window class aperta correttamente\n"); } LayoutBase = IIntuition->OpenClass("gadgets/layout.gadget", 52, &LayoutClass); if(LayoutBase == NULL){ IDOS->Printf("Impossibile ottenere LayoutBase, impossibile aprire LayoutClass\n"); return(0); }else{ IDOS->Printf("Layout Base ottenuta correttamente, classe aperta corretamente\n"); } ButtonBase = (struct ClassLibrary *)IIntuition->OpenClass("gadgets/button.gadget", 52, &ButtonClass); if(ButtonBase == NULL){ IDOS->Printf("Impossibile ottenere ButtonBase, impossibile aprire la ButtonClass\n"); return(0); }else{ IDOS->Printf("Button Base ottenuta correttamente!\n"); } ListBrowserBase = (struct ClassLibrary *)IIntuition->OpenClass("gadgets/listbrowser.gadget", 52, &ListBrowserClass); if(ListBrowserBase == NULL){ IDOS->Printf("Impossibile ottenere ListBrowserBase, impossibile aprire la ListBrowserClass\n"); return(0); }else{ IDOS->Printf("ListBrowserBase ottenuta correttamente!\n"); } IListBrowser = (struct ListBrowserIFace *)IExec->GetInterface((struct Library *)ListBrowserBase,"main",1,NULL); if(IListBrowser == NULL){ IDOS->Printf("Impossibile ottenere ListBrowser Interface\n"); return(0); }else{ IDOS->Printf("ListBrowser Interface ottenuta correttamente\n"); column_info = IListBrowser->AllocLBColumnInfo(2, LBCIA_Column, 0, LBCIA_Title, " GUI Attributes", LBCIA_Width, 80, LBCIA_Column, 1, LBCIA_Title, " BOOL", LBCIA_Width, 20, TAG_END); objects[OID_FINESTRA] = IIntuition->NewObject(WindowClass, NULL, WA_ScreenTitle, "Esempio ListBrowser", WA_Title, "ListBrowser", WA_Width, 800, WA_Height, 600, WA_DragBar, TRUE, WA_CloseGadget, TRUE, WA_SizeGadget, TRUE, WA_DepthGadget, TRUE, WA_Activate, TRUE, WINDOW_IconifyGadget, TRUE, WINDOW_Position, WPOS_CENTERSCREEN, WA_NewLookMenus, TRUE, WA_AutoAdjust, TRUE, WA_InnerWidth, 100, WA_InnerHeight, 100, WINDOW_Layout, objects[OID_LAYOUT_1] = IIntuition->NewObject(LayoutClass, NULL, LAYOUT_Orientation, LAYOUT_ORIENT_HORIZ, LAYOUT_SpaceOuter, TRUE, LAYOUT_DeferLayout, TRUE, TAG_END), LAYOUT_AddChild, objects[OID_LAYOUT_2] = IIntuition->NewObject(LayoutClass, NULL, LAYOUT_Orientation, LAYOUT_ORIENT_VERT, LAYOUT_AddChild, IIntuition->NewObject(LayoutClass, NULL, LAYOUT_Orientation, LAYOUT_ORIENT_VERT, LAYOUT_SpaceOuter, TRUE, LAYOUT_BevelStyle, BVS_GROUP, LAYOUT_Label, " ETICHETTA LISTBROWSER ", // IL LISTBROWSER QUI SOTTO LAYOUT_AddChild, objects[OID_LISTBROWSER] = IIntuition->NewObject(NULL,"listbrowser.gadget", GA_ID, OID_LISTBROWSER, GA_RelVerify, TRUE, GA_TabCycle, TRUE, LISTBROWSER_AutoFit, TRUE, LISTBROWSER_Labels, &listbrowser_list, LISTBROWSER_ColumnInfo, column_info, LISTBROWSER_ColumnTitles, TRUE, LISTBROWSER_ShowSelected, TRUE, LISTBROWSER_Striping, LBS_ROWS, TAG_END), TAG_END), // FINE_BVS_GROUP TAG_END), // FINE_ OID_LAYOUT_2 TAG_END); // FINE OID_FINESTRA make_browserlist(&listbrowser_list, list_strings, tagdatas); if(objects[OID_FINESTRA] != NULL) { struct Window *window = (struct Window *)IIntuition->IDoMethod(objects[OID_FINESTRA], WM_OPEN, NULL); // APRO FINESTRA if(window != NULL) { uint32 signal = 0; IIntuition->GetAttr(WINDOW_SigMask,objects[OID_FINESTRA],&signal); BOOL done = FALSE; while(!done) // FINO A CHE DONE NON DIVENTA TRUE ESEGUI IL CICLO { uint32 wait = IExec->Wait(signal|SIGBREAKF_CTRL_C); if(wait & SIGBREAKF_CTRL_C) // SE UNO DEI DUE OPERANDI E' 0 RESTITUISCE ZERO; SE ENTRAMBI SONO 1 RESTITUISCE 1; SE UNO DEI DUE E' ZERO RESTITUISCE ZERO { done = TRUE; break; } if(wait & signal) { uint32 result = WMHI_LASTMSG; int16 code = 0; while((result = IIntuition->IDoMethod(objects[OID_FINESTRA],WM_HANDLEINPUT,&code)) != WMHI_LASTMSG) // SE NON SONO UGUALI LA CONDIZIONE DIVENTA VERA E QUINDI IL CICLO FINISCE { // QUINDI SICCOME ORA SONO UGUALI IL CICLO CONTINUA switch(result & WMHI_CLASSMASK) //CLASSMASK RESTITUISCE LA PARTE BASSA DELLA WORD (L'ID) { case WMHI_CLOSEWINDOW: window = NULL; done = TRUE; break; } } } } } IIntuition->DisposeObject(objects[OID_FINESTRA]); IListBrowser->FreeListBrowserList(&listbrowser_list); IListBrowser->FreeLBColumnInfo(column_info); if(WindowBase){ IIntuition->CloseClass(WindowBase); IDOS->Printf("\nChiusa la Window class\n"); } if(LayoutBase){ IIntuition->CloseClass(LayoutBase); IDOS->Printf("Chiudo la Layout Class\n"); } if(ButtonBase){ IIntuition->CloseClass(ButtonBase); IDOS->Printf("Chiudo la Button Class\n"); } if(ListBrowserBase){ IExec->DropInterface((struct Interface *)IListBrowser); IIntuition->CloseClass(ListBrowserBase); IDOS->Printf("Chiudo la ListBrowser Class\n"); } if(IntuitionBase){ IExec->DropInterface((struct Interface *)IIntuition); IDOS->Printf("Esco liberando l'interfaccia Intuition \n"); IExec->CloseLibrary(IntuitionBase); IDOS->Printf("Chiudo la libreria Intuition \n"); } if(DOSBase){ IExec->DropInterface((struct Interface *)IDOS); printf("Interfaccia Dos liberata\n"); IExec->CloseLibrary(DOSBase); printf("Chiudo DosLibrary\n\n"); } } return RETURN_OK; } } // FINE MAIN BOOL make_browserlist(struct List *list, char **tagstring, uint32 *bools){ struct Node *node; uint16 num = 0; STRPTR truefalse[] = {"TRUE", "FALSE",NULL}; IExec->NewList(list); while (*tagstring) { if (node = IListBrowser->AllocListBrowserNode(2, LBNA_Column, 0, LBNCA_Text, *tagstring, LBNA_Column, 1, LBNCA_Text, truefalse[bools[num]], TAG_DONE)) { IExec->AddTail(list, node); } else { IDOS->Printf(" AllocListBrowserNode() failed\n"); return(FALSE); } tagstring++; num ++; } return(TRUE); }
GCC error:
list_browser.c: In function 'main': list_browser.c:126: error: dereferencing pointer to incomplete type list_browser.c:224: error: dereferencing pointer to incomplete type list_browser.c:225: error: dereferencing pointer to incomplete type list_browser.c: In function 'make_browserlist': list_browser.c:269: error: dereferencing pointer to incomplete type
struct ListBrowserIFace is not declared at any point in your code, hence the "incomplete type".
add
Add "#include <proto/listbrowser.h>" somewhere at the top, that should fix it
Simon
Thanks for the reply Rigo. I did as you told me and now i have the following error:
I'm guessing ListBrowserBase needs to be a "struct Library *" not ClassLibrary.
If you really need it as a ClassLibrary, then perhaps "#define __NOGLOBALIFACE__" might help.
Simon
Honestly I don't know.. I am learning and, as far as I have understood, ListBrowser gadget is a class so I opened it as a Class and then I got its interface to use its functions.. But i do not know as all the examples i have seen use the -lauto switch during compiling time so, in all the examples, there is no manual opening of the libraries..
As soon as I go back to home i try to use #define __ NOGLOBALIFACE__ and see what happens..
Thanks,
Davide
@Nube
Your new error ("previous declaration of 'ListBrowserBase' was here") stems from the fact that after including "proto/listbrowser.h", your code now contains two conflicting declarations of ListBrowserBase: one in the said include file (where the base is declared as a pointer to struct Library) and the other in your code (where the base is declared as a pointer to struct ClassLibrary).
The ListBrowser Gadget is a BOOPSI class, so its base in fact points to struct ClassLibrary. The SDK include file ("proto/listbrowser.h") declares the base as struct Library * not because there's an error there but for compatibility reasons: older ReAction code opened gadget classes via OpenLibrary(), which returns a pointer to struct Library. Of course in new code you are expected to use - like you do - OpenClass(), which returns a pointer to struct ClassLibrary. But as the first member of this structure is in fact an embedded struct Library, both declarations are fine (as long as you don't mix them up).
So remove the struct ClassLibrary *ListBrowserBase; declaration in line 29 and the error should be gone.
AmigaOne X5000-020 / 2GB RAM / Sapphire Pulse Radeon RX 560 / AmigaOS 4.1 Final Edition Update 2
Hi Trixie thanks for the reply and the hint :-)
i tried to remove the line as you told me and now when i try to compile it I have the following error:
What should i do now?
@Nube
In that case, do this:
- Put back the deleted ListBrowserBase declaration you had in line 29 but change it to
struct Library *ListBrowserBase;
- In your original line 111 change the class opening call to
ListBrowserBase = (struct Library *) IIntuition->OpenClass("gadgets/listbrowser.gadget", 52, &ListBrowserClass);
- In your original line 241 change the class closing call to
IIntuition->CloseClass((struct ClassLibrary *) ListBrowserBase);
AmigaOne X5000-020 / 2GB RAM / Sapphire Pulse Radeon RX 560 / AmigaOS 4.1 Final Edition Update 2
Thanks Trixie, now it compiles but the program doesn't work.. I have a gr at the startup..
here is the update version of my code:
I think i missing something to have a listbrowser in my code..
no wait... the program opened after i pressed "ignore" in the gr popup window.. it took about 5 to 7 minutes but it is an empty window without listbrowser inside.. definitly i am missing something... the funny thing is that amiga os didn't freeze and the program opened..
When i try to post the crash log i have an internal server error...
another thing, why my avatar is gone?
@Nube
I compiled your code and determined that the crash is due to giving an uninitialized list to Intuition. You should probably be using ASOT_LIST instead of the old Exec->Newlist. Here are the changes I made to prevent the crash.
Changed line 36 to "struct List *listbrowser_list;" so it's a pointer.
Removed line 266.
Changed line 170 to "LISTBROWSER_Labels, listbrowser_list," //removed the &
Added "IExec->FreeSysObject(ASOT_LIST, listbrowser_list);" below line 224.
Added the following lines right above line 135:
if (!(listbrowser_list = (struct List *)IExec->AllocSysObject(ASOT_LIST, NULL)))
{
return 0;
}
The program stopped crashing but just opens an empty window. Maybe someone else can find more corrections that need to be made.
X1000 - OS 4.1FE
That ones easy :-)
The code builds the list *after* attaching it to the Listbrowser. You must never do that.
For the simple case move the call to make_browserlist() at line 183 before the NewObject() call at line 137;
For the general case of updating the list whilst the program is running the process is roughly
Remove the list from the listbrowser (SetAttrs(lb,LISTBRWOSER_Labels, ~0,TAG_DONE);
Make required changes to list
Re add to listbrowswer
SetGadgetAttrs(lb,window,NULL,LISTBROWSER_Lables,list,TAG_DONE);
Possibly use RefreshSetGadgetAttrs().
Note don;t use SetGadgetAttrs() when removing. THis prevent an flicker in the window while the list is removed. DO replace the is list as quickly as possible.
I moved make_browserlist() but I still get an empty window. Maybe there's another error. Heres the code I compiled (with changes):
X1000 - OS 4.1FE
Thanks to all for the help, really appreciated. It is not easy to learn amiga os coding from scratch and as you can see most of the examples included in the sdk are outdated and it is not easy to understand how to proceed.. By the way I will continue investigating on how to create/insert a listbrowser gadget in my code :-)
@Nube
Your code crashed because you were passing an unitialized listbrowser list to your NewObject() call. Note in your original code that the
make_browserlist()
function is called in line 181 after you have created the listbrowser object! This cannot possibly work - the list must be initialized before you pass it to NewObject() via LISTBROWSER_Labels.Edit: Sorry, didn't realize Andy already beat me to it :-)
AmigaOne X5000-020 / 2GB RAM / Sapphire Pulse Radeon RX 560 / AmigaOS 4.1 Final Edition Update 2
Hi, you have a TAG_END in GUI too "early" (closing/finishing the window contents/lyout):
and put it at the end of GUI creation:
there is a PDF/guide to ReAction GUI code in os4depot (http://www.os4depot.net/share/document/development/reactionguide.lha)
And enable "IExec->NewList(list);" in make_browserlist() code.
And maybe move the Disposing() out of the "if(objects[OID_FINESTRA] != NULL)" , to make sure objects are disposing even if windows object couldn't be created.
AOS4.1/SAM460ex/PPC460EX-1155MHZ/2048MB/RadeonHD6570/SSD120GB/DVDRW :-P
@Nube
No, don't. The list initialization is handled by
IExec->AllocSysObject(ASOT_LIST, NULL)
in line 137, so no need for NewList() here.AmigaOne X5000-020 / 2GB RAM / Sapphire Pulse Radeon RX 560 / AmigaOS 4.1 Final Edition Update 2
Thanks to all, I will find the solution and post it here! :-)
@jabirulo
Good catch. The program compiles & works now. As Trixie pointed out, The IExec->NewList() function was replaced with the ASOT_LIST allocation (which also initializes the list). I should have removed it instead of commenting it out.
X1000 - OS 4.1FE
@Nube
And may I join the party and chime in as well?
My eye fell on this part:
But DOS library is nowhere opened explicitly in your code. What's more: DOS library is one of those libraries which is ALLWAYS open and, hence, should not be closed manually/explicitly.
Furthermore, you do some allocations like IListBrowser->AllocLBColumnInfo(), but you do not test for success/failure. Not wrong per sé, but it's better to check every possible step in the process.
My 0.02 euro...
Ok, I'm off again.
OldFart
@trixie
Ok thx didn't know.
Just courosity, any benefits (saves memory, "faster",..) to use ASOT_LIST instead of NewList()?
TIA
AOS4.1/SAM460ex/PPC460EX-1155MHZ/2048MB/RadeonHD6570/SSD120GB/DVDRW :-P
AllocSysObject allocates new memory and returns a pointer to it. This memory needs to be freed before you leave the program.
NewList takes a pointer to an already allocated block of memory.
If your struct List is part of another struct you would use NewList. For example in a hierarchical data type where nodes can have child-lists.
At the end I was able to create a little demo that use one column listbrowser gadget inside a window. it is a very basic example but enough for me to understand how to create a list and how to use a listbrowser gadget. Here the working example:
@Nube
Change line 49 to this:
to avoid a warning when compiling with the -Wwrite-strings flag. I recommend using this along with -Wall -Werror as your standard compile flags in all your projects.
AmigaOne X5000-020 / 2GB RAM / Sapphire Pulse Radeon RX 560 / AmigaOS 4.1 Final Edition Update 2
Thanks for the information trixie! i'll do it!