Using Newlib in a library

This forum is for general developer support questions.
User avatar
Olrick
Posts: 70
Joined: Mon Mar 07, 2011 3:24 pm
Location: Rennes, France

Using Newlib in a library

Post by Olrick »

Hi,

I'm writing my first OS4 library and my current code uses some libc functions. As I'm using Newlib, gcc complains about INewlib not being defined.
My questions are:
- is it ok to use Newlib in a library ?

- apart from getting rid of it, what's the way to using Newlib in a library ? I could not find information about INewlib interface in the SDK.

TIA
God grant me the Serenity to accept the things I cannot change; Courage to change the things I can; and Wisdom to know the difference.
User avatar
tonyw
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 1479
Joined: Wed Mar 09, 2011 1:36 pm
Location: Sydney, Australia

Re: Using Newlib in a library

Post by tonyw »

Sure you can use newlib from within a library. The only problem is that the vector INewlib must be defined as global. It is common to allocate the variable and initialise it in the start() function, eg:

Code: Select all

struct	Library	*NewlibBase;
struct	Interface	*INewlib;

		NewlibBase = IExec->OpenLibrary ("newlib.library", 53);
		if (NewlibBase == NULL)
		{
			IExec->DebugPrintF("Can't open V53 newlib.library\n");
			break;
		}

		INewlib = (struct Interface *)IExec->GetInterface (NewlibBase, "main", 1, NULL);
		if (INewlib == NULL)
		{
			break;
		}
Of course, you should DropInterface() when you exit.

Note that on some machines like the X-1000 with its CFE, bss variables are not cleared at task initialisation. To be safe, always clear all your global variables to zero right at the start of your code.

Once you have it defined (as global, not static) in your startup code, it should be visible to all other source modules. You will find that there is a line somewhere (in one of the common headers) that says:
"extern struct Interface *INewlib" or something like that. The rest is automatic.
cheers
tony
User avatar
Olrick
Posts: 70
Joined: Mon Mar 07, 2011 3:24 pm
Location: Rennes, France

Re: Using Newlib in a library

Post by Olrick »

Thank you for your fast answer.

I'm wondering what happens when different applications open the library simutaneously. I thought global variables would be a problem. Does the library have to manage the sharing of the variable or does each process get its own global variable ?

Should that kind of global variable solution be used for all interfaces ? Until now I was storing library bases and interfaces (IExec, IIntuition ...) into my library base.
God grant me the Serenity to accept the things I cannot change; Courage to change the things I can; and Wisdom to know the difference.
User avatar
broadblues
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 600
Joined: Sat Jun 18, 2011 2:40 am
Location: Portsmouth, UK
Contact:

Re: Using Newlib in a library

Post by broadblues »

Olrick wrote:Thank you for your fast answer.

I'm wondering what happens when different applications open the library simutaneously. I thought global variables would be a problem. Does the library have to manage the sharing of the variable or does each process get its own global variable ?
You should open Open newlib.library and get the interface in the lib_init() and close it in lib_expunge() functions of the library.
In this case it does need to be a global as the clibrary calls reference that INewlib variable.

It doesn't mattter for INewlib as the context information is stored in the Process structure for each Process using the library, not in the libary interface, so it's safe to share.
User avatar
Olrick
Posts: 70
Joined: Mon Mar 07, 2011 3:24 pm
Location: Rennes, France

Re: Using Newlib in a library

Post by Olrick »

Ok, thank you both for the support.
Once my library is validated, I will contribute to the wiki.
God grant me the Serenity to accept the things I cannot change; Courage to change the things I can; and Wisdom to know the difference.
User avatar
Olrick
Posts: 70
Joined: Mon Mar 07, 2011 3:24 pm
Location: Rennes, France

Re: Using Newlib in a library

Post by Olrick »

Here is a new question:
How should I handle an error during libInit() (example: can't open another library) and abort cleanly my library opening sothat the user application get informed ?

TIA
God grant me the Serenity to accept the things I cannot change; Courage to change the things I can; and Wisdom to know the difference.
User avatar
tonyw
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 1479
Joined: Wed Mar 09, 2011 1:36 pm
Location: Sydney, Australia

Re: Using Newlib in a library

Post by tonyw »

You must return NULL to the caller so that she knows it failed. There is no provision for returning an error code, so any error reports must be created some other way.

The easiest way is to open DOS and make up a TimedDosRequester() with your message. For example, this code reports that a library (or a handler in this case) found an old version of DOS:

Code: Select all

CONST TEXT youNeed[] = "You need dos.library 53.95+\nYou only have V%ld.%ld\n\n";

// This line prints a message on the serial debug output
IExec->DebugPrintF (youNeed, DOSBase->lib_Version, DOSBase->lib_Revision);

// This line makes up the requester
IDOS->TimedDosRequesterTags(
			TDR_Timeout,		30,
			TDR_NonBlocking,	TRUE,
			TDR_TitleString,	VSTRING,
			TDR_FormatString,	youNeed,
			TDR_GadgetString,	"OK",
			TDR_ImageType,		TDRIMAGE_ERROR,
			TDR_Arg1,			(int32)DOSBase->lib_Version,
			TDR_Arg2,			(int32)DOSBase->lib_Revision,
			TAG_END);

// Now clean up, exit and return NULL
cheers
tony
User avatar
Olrick
Posts: 70
Joined: Mon Mar 07, 2011 3:24 pm
Location: Rennes, France

Re: Using Newlib in a library

Post by Olrick »

Thank you Tonyw

I guessed I have to return NULL, as that's what happens for any library. But my wonder is: should I clean up the LibraryBase or will libExpunge() be called automagically to do it ?
God grant me the Serenity to accept the things I cannot change; Courage to change the things I can; and Wisdom to know the difference.
User avatar
broadblues
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 600
Joined: Sat Jun 18, 2011 2:40 am
Location: Portsmouth, UK
Contact:

Re: Using Newlib in a library

Post by broadblues »

If libInit() fails the library wont be loaded, so I don;t think expeunge can be called, so you must call your cleanup function.

It's a good idea to seperate your cleanup routine into a function that can be called from both libInit() on failure and libExpunge() on expunge.
User avatar
Olrick
Posts: 70
Joined: Mon Mar 07, 2011 3:24 pm
Location: Rennes, France

Re: Using Newlib in a library

Post by Olrick »

I was thinking about the cleaning instructions generated in libExpunge() by IDLTool:

Code: Select all

        
        libBase->IExec->Remove((struct Node *)libBase);
        libBase->IExec->DeleteLibrary((struct Library *)libBase);
I thought it was the cleanup of the LibraryBase I get in libInit(), was I wrong ?
And is there anything to do with the segList I get from libInit() ?

I guess these two resources got allocated and must be freed in case of failure.
God grant me the Serenity to accept the things I cannot change; Courage to change the things I can; and Wisdom to know the difference.
Post Reply