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

Reply via email to