I've tried the below code in Windows and FreeBSD. In both cases, it can load
some, but not all functions from the DLLs/SOs. Does anyone know what I'm doing
wrong? I am using the DLLs downloaded from here:
http://libagar.org/download.html.en (MSVC - agar-1.4.1-win32-i386.zip) and
building Agar in FreeBSD.
Thanks,
-Jim Stapleton
===== test.c =====
/* Public domain */
/*
* Test dynamic loading of libagar
*/
//compile:
//in the Visual Studio command line:
// cl test.c && test.exe
//in *NIX
// gcc test.c && ./a.out
#include <stdio.h>
//#include <agar/core.h>
//#include <agar/gui.h>
#ifdef _WIN32
#define COREDL "c:/windows/ag_core.dll"
#define GUIDL "c:/windows/ag_gui.dll"
#include <windows.h>
#define DLTYPE HINSTANCE
#else
#define COREDL "/usr/local/lib/libag_core.so"
#define GUIDL "/usr/local/lib/libag_gui.so"
#include <dlfcn.h>
#define DLTYPE void *
#endif
char esbuff[1000];
//dynamic library references
DLTYPE dl_agcore = NULL;
DLTYPE dl_aggui = NULL;
int (*AG_Getopt)(int argc, char * const argv[], const char *, char **, int*);
int (*AG_InitCore)(const char * title, int flags);
char* (*AG_GetError)(void);
int (*AG_InitGraphics)(const char * drv);
void (*AG_Destroy)(void);
//something I know is exported
void (*AG_SDL_BlitSurface)(void*, void*, void*, int, int);
//like dlload, but return a non-zero on error, and printf a message
int edload(void **handle, char *name, int flags);
int loadfn(void **fn, void *handle, char *name, char *handle_name);
void cleanup();
//load all function pointers we use
int fpinit();
int main(int argc, char *argv[])
{
int ret=-1;
fprintf(stderr, "executing main\n");
if(fpinit()==0)
{
ret=_main(argc, argv);
}
else
{
fprintf(stderr, "Failed to load dynamic libraries. Last error: %s", esbuff);
}
cleanup();
return ret;
}
int _main(int argc, char *argv[])
{
//AG_Window *win;
char *driverSpec = NULL, *optArg;
int c, i;
fprintf(stderr, "Parsing opts.\n");
while ((c = AG_Getopt(argc, argv, "?hd:", &optArg, NULL)) != -1)
{
switch (c)
{
case 'd':
driverSpec = optArg;
break;
case '?':
case 'h':
default:
printf("Usage: windows [-d agar-driver-spec]\n");
return (1);
}
}
fprintf(stderr, "Core Init.\n");
if (AG_InitCore("agar-windows-demo", 0) == -1)
{
fprintf(stderr, "%s\n", AG_GetError());
return 1;
}
printf("After Core Init success/AGERR: %s\n\n",AG_GetError());
AG_Destroy();
return (0);
}
int fpinit()
{
char errstr;
fprintf(stderr, "loading libraries.\n");
if((errstr = esdlo(&dl_agcore, COREDL, 0))) return 1;
if((errstr = esdlo(&dl_aggui, GUIDL, 0))) return 1;
fprintf(stderr, "loading functions.\n");
//test, should work
if(loadfn((void**)(&AG_SDL_BlitSurface), dl_aggui, "AG_SDL_BlitSurface",
"ag_gui")) return 1;
if(loadfn((void**)(&AG_Getopt), dl_agcore, "AG_Getopt",
"ag_core")) return 1;
if(loadfn((void**)(&AG_InitCore), dl_agcore, "AG_InitCore",
"ag_core")) return 1;
if(loadfn((void**)(&AG_GetError), dl_agcore, "AG_GetError",
"ag_core")) return 1;
if(loadfn((void**)(&AG_Destroy), dl_agcore, "AG_Destroy",
"ag_core")) return 1;
if(loadfn((void**)(&AG_InitGraphics), dl_aggui, "AG_InitGraphics", "ag_gui"))
return 1;
fprintf(stderr, "done.\n");
return 0;
}
void cleanup()
{
#ifdef _WIN32
if(dl_agcore) FreeLibrary(dl_agcore);
if(dl_aggui) FreeLibrary(dl_aggui);
#else
if(dl_agcore) dlclose(dl_agcore);
if(dl_aggui) dlclose(dl_aggui);
#endif
}
int loadfn(void **fn, DLTYPE handle, char *name, char *handle_name)
{
#ifdef _WIN32
(*(FARPROC*)(fn)) = GetProcAddress(handle, name);
#else
*fn = dlsym(handle, name);
#endif
if(!(*fn))
{
sprintf(esbuff, "Error loading function %s::%s\n", handle_name, name);
return 1;
}
return 0;
}
int esdlo(DLTYPE *handle, char *name, int flags)
{
#ifdef _WIN32
(*handle) = LoadLibrary(name);
#else
(*handle) = dlopen(name, flags);
#endif
if(!(*handle))
{
#ifdef _WIN32
#else
sprintf(esbuff, "Error loading dll %s (%s)\n", name, dlerror());
#endif
printf(esbuff);
return 1;
}
return 0;
}
_______________________________________________
Agar mailing list
[email protected]
http://libagar.org/lists.html