Amiga.org
Operating System Specific Discussions => Amiga OS => Amiga OS -- Development => Topic started by: jonssonj on March 07, 2004, 12:19:14 PM
-
Hello!
Im reading my RKRM Libraries manual and Im trying to do the first sample, that uses the DisplayBeep() function.
Im using Storm C V4 GUI but with the Storm C V3 Compiler.
My program looks like this:
#include
#include
/* Get storage for the library base. The base Name must be IntuitionBase */
struct IntuitionBase *IntuitionBase;
int main()
{
IntuitionBase = (struct IntuitionBase *) OpenLibrary("Intuition.library", 33L);
if (IntuitionBase) {
DisplayBeep(0L);
CloseLibrary(IntuitionBase);
} else {
exit(20);
}
}
When I try to compile this program I get the following error
Error: In function `int main()´:
type `Library´ is not a base type for type `IntuitionBase´
OpenLib.cpp Line 11
Can someone tell what the heck is going on?
Its frustrating to get stuck on the first example... :)
/Jörgen
-
Hi Jorgen,
Try and switch to gcc compiler in favor of Storm V3.
I've tried your little example with the gcc compiler: it works! But when switching to Storm C3 all I get is an error in line 12: Illegal argument: CloseLibrary(IntuitionBase); This one is to be resolved like this: CloseLibrary(Library *)IntuitionBase); Under Storm C3 it compiles and yes your screen flashes! On the other hand flashing the screen to draw a user's attention is a bad, bad practice. There are far more userfriendly ways to communicate with the user when it comes to drawing attention.
Keep going on! Working from simple programs onwards is the best way of teaching yourselves how to program and don't forget 'borrowing' code from someone else. It may come in very, very handy at times...
Cheers mate. Oh, ehm, one more remark, but admittedly very personel is the style of writing. Personally I prefer to do it this way:
int main(void)
{ if (IntuitionBase = OpenLibary("intuition.library", 33L))
....{DisplayBeep(0L);
....}
..else
....{exit(20);
....}
}
It makes it far more readable and therefore easier to maintain. I've gone sofar as to indenting every next level by only two positions, while 4 is considered default. But as I said it is just a matter of personal taste.
Regards,
Tjitte
P.S. Indentation is not shown correctly, as blanks at the beginning of a line are removed. Therefore I've replaced them with dots.
-
int main(void)
{ if (IntuitionBase = OpenLibary("intuition.library", 33L))
{DisplayBeep(0L);
}
else
{exit(20);
}
}
Use the code tag ((http://www.amiga.org/images/code.gif) symbol) and then it will be displayed correctly :-)
-
int main(void)
{ if (IntuitionBase = OpenLibary("intuition.library", 33L))
....{DisplayBeep(0L);
....}
..else
....{exit(20);
....}
}
It's a matter of opinion indeed. IMHO embedding '{' and code on the same line is not the clearest possible way (moving code blocks gets tedious then). Not to mention your example doesn't build at all (due to missing casts, and typos).
Here is how I would do it:
#include <exec/execbase.h>
#include <dos/dos.h>
#include <intuition/intuitionbase.h>
#include <proto/exec.h>
#include <proto/intuition.h>
struct ExecBase *SysBase;
struct IntuitionBase *IntuitionBase;
int main(void)
{
int ret = RETURN_FAIL;
SysBase = *(struct ExecBase **)4;
IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 33);
if (IntuitionBase)
{
DisplayBeep(NULL);
ret = RETURN_OK;
CloseLibrary((struct Library *) IntuitionBase);
}
return ret;
}
-
CloseLibrary requires a pointer of type Library. So you need to cast IntuitionBase as a library.
e.g.
CloseLibrary((struct Library *)IntuitionBase);
Then it should compile ok.
-
@Piru
One is never too old to learn... ;->
Regards,
Tjitte
-
You are right. I forgot. I'm getting old. BTW, what was this all about? ;->
Cheers,
Tjitte
-
@CD32Freak
Thanks for the tip. I always wondered how suchs things were done. I'm in debt with you over this one...
Cheers,
Tjitte
-
Thanks to all of you, for all your replys.
@Jettah
My intention is not to draw the user's attention this way. I'm only doing the sample program in the RKRM Library manual. But thanks for the point... :-) About the layout of my program, I did not know that the spaces disappeared in the message when pressing the submit button. All my programs that I write are usually indented.
@Piru
I saw that you includes a lot more header files. Is this really neccessary? I thought your example was a bit complicated just to show the use of DisplayBeep.
Anyway, thanks to you all for the help.
/Jörgen
-
I saw that you includes a lot more header files. Is this really neccessary?
IMO yes.
for struct ExecBase
for RETURN_#?
for struct IntuitionBase
for OpenLibrary()/CloseLibrary()
for DisplayBeep()
I thought your example was a bit complicated just to show the use of DisplayBeep.
Well, most compilers have autoopen for libraries. But since the intuition.library was explicitly opened already, I decided to make it all startup-code -free. This added some complexity. I also removed some clear un-amiga call: exit().
Also, I wanted to present proper example, that actually builds and works, with most compilers, and without warnings.
-
@Piru
Thanks a lot for your help. :-) I appreciate it a lot. One more thing though, why do you call exit "an un-amiga call"? It is used in the RKRM Libraries manual.
/Jörgen
-
One more thing though, why do you call exit "an un-amiga call"?
exit() terminates execution of the application, only calling routines added by atexit(), (and executing destructors, if any).
This indeed works ok for standard C applications that use ANSI C filehandles (fopen), memory (malloc) and such only, these are released properly at exit() call.
However, AmigaOS resources are NOT released at all, unless if you expicitly add cleanup routine with atexit().
As such, using exit() in Amiga application is not a good design IMO.
Take this (buggy) example:
#include <dos/dos.h>
#include <proto/exec.h>
#include <proto/dos.h>
int main(void)
{
BPTR fh;
fh = Open("t:testfile", MODE_NEWFILE);
if (fh)
{
struct Library *SomeBase;
SomeBase = OpenLibrary("some.library", 0);
if (!SomeBase)
{
/* BUG: note that fh is not closed */
exit(20);
}
CloseLibrary(SomeBase);
Close(fh);
}
return 0;
}
-
Ok, thanks!
Now I am on my amiga at home and I have right now tryed your example. The code compiles and links ok, but when I run the program, I can´t see anything that flashes and I can´t hear any beep either.
When I debug the program, it seems like it calls the function DisplayBeep(NULL);
What is wrong?
One more question, How do I add variables to the storm C V4 watch window, when I debug a program?
/Jörgen
-
@jonssonj
Maybe you disabled all DisplayBeep() actions in Prefs.
-
I will check that out when I get home tonight.
Is there anyone out there with more suggestions?
/Jörgen
-
If you're using P96 you won't see the screen flash. You should still hear the beep tho...
-
Aha, that's the thing then... But as you said I should hear the beep.
Where does this beep sound come from? is it played through AHI or is it output through the Amigas RCA connectors on the back?
/Jörgen
-
It's played via the RCA connectors as it uses Paula. But IIRC correctly in OS3.9 you have the option to play back system sound through AHI and an apropriate datatype (included). I think an env-variable had to be set for that.