/*
 *	usepkg1_via_dl: let's try to use pkg1 via libdl
 */

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>


//
// void *p = lookup_function( void *dl, char *module, char *funcname );
//	look within dl, a dynamic library opened by dlopen(), for
//	the global symbol <funcname>.
//	If we find it, return a pointer to it. If not, return NULL.
//
void *lookup_function( void *dl, char *module, char *funcname )
{
	// can we look up the symbol funcname inside the dl?
	void *p = dlsym( dl, funcname );
	if( p != NULL )
	{
		printf( "Have found %s in %s\n", funcname, module );
		return p;
	}

	printf( "Not found %s in %s\n", funcname, module );
	return NULL;
}


// void_void_f: a pointer to a void->void function
typedef void (*void_void_f)( void );


int main( void )
{
	char *module = "pkg1";

	char libname[1024];
	sprintf( libname, "lib%s.so", module );

	// open the shared library
	void *dl = dlopen( libname, RTLD_NOW );
	if( dl == NULL )
	{
		fprintf( stderr, "Can't dlopen %s\n", libname );
		return 1;
	}

	void_void_f f1 = lookup_function( dl, module, "f1" );
	if( f1 == NULL )
	{
		fprintf( stderr, "Can't find f1 in %s\n", libname );
		return 1;
	}

	// ok, now we have f1, a pointer to pkg1's f1 or pkg1_f1 function.
	// we can't check yet that that function is a void->void function,
	// so let's just call it:
	(*f1)();

	return 0;
}
