Welcome, Guest. Please login or register.

Author Topic: Compiler  (Read 13967 times)

Description:

0 Members and 1 Guest are viewing this topic.

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16882
  • Country: gb
  • Thanked: 6 times
    • Show all replies
Re: Compiler
« on: June 01, 2003, 11:43:38 AM »
Hi all,

Sorry Cymric ;-) I managed to miss this thread - I haven't been in the developer forums much lately. I'm up to my eyes in some coding at the moment and come to amiga.org to get a break from it :-)

Standard C / C++ code pass arguments to a function on the stack (a unix convention). The amiga libraries have an assembly level interface that works differently. Arguments are passed along in registers and a pointer to the library is passed in register a6.

To call amiga libraries from C, compilers have to generate the appropriate calling convention for a function (ie save off any registers that may get trashed, load the arguments and to a jsr to the code).

Naturally there are several ways of doing this. Inline assembly, stub libraries or #pragmas.

Any #pragma is compiler dependent (that being the point of pramas). IIRC StormC goes this route (with amicall / tagcall).

AFAIK, as Cymric says, gcc basically goes the inline assembly / stub link library way.

In any event, I strongly reccomend the inline asm header approach for performance critical code. Otherwise (with the link libraries) you are calling a function to call a function. Naturally this introduces some additional overhead. Not really much of an issue for GUI related stuff I guess...

I'm not actually using gcc at the moment, but IIRC there was a tool for creating gcc compatible stub .lib files from fd files?

Keep on plugging away at it. I'm sure you'll get there.
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16882
  • Country: gb
  • Thanked: 6 times
    • Show all replies
Re: Compiler
« Reply #1 on: June 01, 2003, 12:06:20 PM »
Quote

quiesce wrote:
If my understanding of the latter is correct, how can I prevent the program from complaining about the absence of a function that comes from a .library file?


It is. shared libraries have version numbers. From the documentation on a library, choose the minimum version that fully supports all the functions of that library you intend to use.
The OpenLibrary() call supports a minimum version number that you specify (often left as zero if you don't care which version). You give this as the second argument eg:

/* Open at least v41 of intuition.library */
IntuitionBase = OpenLibrary("intuition.library", 41);

OpenLibrary() will return NULL if either the library isn't available (should never happen for intuition btw ;-)  ) or isn't available in at least the version you asked for. Simply test the return value for NULL and handle accordingly (maybe put up an error message and cleanly exit the program).
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16882
  • Country: gb
  • Thanked: 6 times
    • Show all replies
Re: Compiler
« Reply #2 on: June 01, 2003, 04:40:15 PM »
Actually that wasn't a very good example :-)

IntuitionBase is not a standard Library (in that it has extended stuff in it)

What I should have written int that example was

struct IntuitionBase *IntuitionBase;

IntuitionBase = (struct IntuitionBase*)OpenLibrary("intuition.library", 41);

/* we can check if we opened it ok by testing if IntuitionBase is not NULL */

But the general idea is the same for all libraries.
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16882
  • Country: gb
  • Thanked: 6 times
    • Show all replies
Re: Compiler
« Reply #3 on: June 01, 2003, 04:57:40 PM »
Hi quiesce,

Ah, the wonders of multithreading :-)

Creating multithreaded code has its complications. But generally what you do is to define a function that serves as the entry point for the new thread.

The next thing is to create a thread and tell it to launch from that address. You have two choices under amiagos

1) Use an exec.library Task

Tasks are lightweight and do not use many resources. Their principal drawback is that they cannot use dos.library or anything else which may use it (eg normal C IO mechanisms).

Use tasks when character IO is not important for your code.

You need to look at exec.library/AddTask() or amiga.lib/CreateTask()

Eg :

struct Task* myTask;

void myTaskMain()
{
   /* code for myTask */
}

/* struct Task* CreateTask(name, pri, entry, stacksize)*/

myTask = CreateTask("mytask", 0, myTaskMain, 4096);

2) Use a dos.library Process

This is an exec.library task extended with the various handles that allow it to use the dos.library. It's pretty much complete. You need to look at dos.library/CreateNewProc(). This call returns a struct Process* (castable to struct Task*) and takes a range of arguments as a taglist.

If you do go for multithreading, you need to protect data that is used from parallel threads. You have to ensure that modifications to data are exclusive. For this you need to look at Signal Semaphores (see exec.library manuals).

You will also need to look at signalling and sending messages such that your threads can norify each other. An understanding of how exec works is very handy here.

It sounds a bit more complex than it is but it's also not for the beginner either.
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16882
  • Country: gb
  • Thanked: 6 times
    • Show all replies
Re: Compiler
« Reply #4 on: June 02, 2003, 07:37:14 PM »
Heh, I think it's high time this thread was moved to the developer forum ;-)

First and foremost, the prototypes for DoMethod() and DoMethodA() are in clib/alib_protos.h

If you want to indent your source for posting you need to use a non breaking space "& nbsp;" without the space between the & sign and the nbsp; bit (I had to seperate them here otherwise it would be parsed into a real non-breaking space and you wouldn't see it) (thanks to Tickly for telling me that originally ;-) )

A couple of small points that you should consider. How about returning a BOOL from InitLibs() that returns true if the library was opened and false if not? Then you can cleanly exit your program without a crash on systems where v19 of the muimaster.library is not available.

This could be as simple as

BOOL InitLibs()
{
  return (MUIMasterBase = OpenLibrary("muimaster.library", 19)) ? TRUE : FALSE;
}

Incidentally, IIRC the use of void to signify no function arguments is deprecated since ANSI C v2. It certianly is in C++ ;-)
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16882
  • Country: gb
  • Thanked: 6 times
    • Show all replies
Re: Compiler
« Reply #5 on: June 02, 2003, 09:40:40 PM »
I dunno exactly. Maybe because it's a waste of typing ? :-P

I'm talking about void in argument lists eg

void function(void);

You can just write empty brackets instead:

void function();

Nothing in the brackets means no arguments expected. I think they borowed this from C++ and to give better upwards compatibility with it.
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16882
  • Country: gb
  • Thanked: 6 times
    • Show all replies
Re: Compiler
« Reply #6 on: June 02, 2003, 09:42:37 PM »
Actually you might want to check for yourself. I recall reading it in whitepapers on C (esp the ISO 1999 standard) but I may be wrong.

I do know that older C interprets empty brackets as 'no information given' about arguments.

This was deemed unnaceptable in C++ so they opted for the empty brackets means no arguments approach. Which makes more sense anyway ;-)
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16882
  • Country: gb
  • Thanked: 6 times
    • Show all replies
Re: Compiler
« Reply #7 on: June 02, 2003, 09:53:06 PM »
Have you tried it on a real miggy? Send it over if you like...
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16882
  • Country: gb
  • Thanked: 6 times
    • Show all replies
Re: Compiler
« Reply #8 on: June 02, 2003, 10:03:54 PM »
Well, I meant to see if it bails out here too.

Incidentally, did you add the checks for the library open (see my earlier post) ?

Tying to use a library that isn't open will cause all kinds of mayhem.

-edit-

I seem to recall there were some crashes on the amiga side that the emulator cant cope with so it exits. I've seen it happen before somewhere...
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16882
  • Country: gb
  • Thanked: 6 times
    • Show all replies
Re: Compiler
« Reply #9 on: June 02, 2003, 10:09:44 PM »
Looking back at your code post, don't you need to create the object before you go setting its parameters?

-edit-

sorry, I just saw that you did
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16882
  • Country: gb
  • Thanked: 6 times
    • Show all replies
Re: Compiler
« Reply #10 on: June 02, 2003, 10:12:53 PM »
Have you put any runtime pointer checks to make sure that your objects are created?

Each time you create something just add a little check to make sure the pointer is not NULL.

This goes for libraries too...
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16882
  • Country: gb
  • Thanked: 6 times
    • Show all replies
Re: Compiler
« Reply #11 on: June 03, 2003, 01:12:15 AM »
To be honest I haven't done any MUI coding, but BOOPSI is pretty much all alike.
Send me the executable just to see if I can get any crash info. Perhaps it's not your program at fault...
int p; // A