Motivation of interfaces

This forum is for general developer support questions.
Post Reply
User avatar
jaokim
Beta Tester
Beta Tester
Posts: 92
Joined: Sat Jun 18, 2011 1:41 am

Motivation of interfaces

Post by jaokim »

With AmigaOS 4 we got libraries with interfaces. What was the motivation behind adding this extra layer?
I think it is nice to be able to f.i. like in exec.library have a debug interface, but most of the time as a developer using a library, it only adds two extra GetIface/DropIface calls, together with a interface pointer to keep track of, besides the library pointer. Furthermore, not only do I need to keep track of the library's name, but also know if it has a "main" interface or if this particular library calls it something else.

Besides the debug interface of exec, I've yet to find any real usage of it. The application.library has two interfaces: "application" and "prefsobject", but I don't see the real advantage here.
User avatar
salass00
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 534
Joined: Sat Jun 18, 2011 4:12 pm
Location: Finland
Contact:

Re: Motivation of interfaces

Post by salass00 »

@jaokim

The main reason is to have separate entry points for legacy (M68k) and native (PPC) programs so that the native programs do not have to adhere to obsolete M68k calling conventions as in another OS. Other advantages include less namespace pollution, limited OO-like capabilities (used f.e. by AmiDock dockies system and PCI interface in expansion.library) and so on.

The interface system also provides a strict versioning scheme so a library can export several incompatible versions of the same interface (older interface versions may have compatibility cludges f.e. that are not needed in newer ones that will only be used by newer programs).

FWIW to make it less work to open and close library interfaces when creating the TuneNet UADE plugin I created functions OpenInterface() and CloseInterface() which combine the effects of OpenLibrary()/CloseLibrary() and GetInterface()/DropInterface() into two easy to use functions:

Code: Select all

static APTR OpenInterface (CONST_STRPTR lib_name, int32 lib_vers,
	CONST_STRPTR int_name, int32 int_vers)
{
	struct Library *library;
	struct Interface *interface;
	library = IExec->OpenLibrary(lib_name, lib_vers);
	if (library) {
		interface = IExec->GetInterface(library, int_name, int_vers, NULL);
		if (interface) {
			return interface;
		}
		IExec->CloseLibrary(library);
	}
	return NULL;
}

static void CloseInterface (APTR interface) {
	if (interface) {
		struct Library *library = ((struct Interface *)interface)->Data.LibBase;
		IExec->DropInterface(interface);
		IExec->CloseLibrary(library);
	}
}

static BOOL OpenLibs (void) {
	if ((IDOS = OpenInterface("dos.library", 52, "main", 1)) &&
		(IUtility = OpenInterface("utility.library", 52, "main", 1)) &&
		(INewlib = OpenInterface("newlib.library", 52, "main", 1)))
	{
		IXpk = OpenInterface("xpkmaster.library", 5, "main", 1);
		IXfd = OpenInterface("xfdmaster.library", 39, "main", 1);
		return TRUE;
	}
	CloseLibs();
	return FALSE;
}

static void CloseLibs (void) {
	CloseInterface(IXfd);
	CloseInterface(IXpk);
	CloseInterface(INewlib);
	CloseInterface(IUtility);
	CloseInterface(IDOS);
}
Post Reply