/*

DLL file class for Windows, Linux and BSD.

Author: Matthew William Coan
Date: Fri Jan  7 20:50:58 EST 2011

*/

#ifndef _DLL_FILE_H
#define _DLL_FILE_H

#include <string>

//#define OS_UNIX
//#define OS_WINDOWS

#ifdef OS_UNIX
#include <dlfcn.h>
#endif
#ifdef OS_WINDOWS
#include <windows.h>
#endif

using namespace std;

#ifdef OS_WINDOWS
extern "C" {
typedef void * (*pf_t)();
extern pf_t get_proc_address(HINSTANCE h, const char * name);
}
#endif

class dll_file {
#ifdef OS_WINDOWS
   HINSTANCE _pointer;
#endif
#ifdef OS_UNIX
   void * _pointer;
#endif

public:
   dll_file(const char * str) {
#ifdef OS_UNIX
      _pointer = dlopen(str, RTLD_LAZY);
#endif
#ifdef OS_WINDOWS
      _pointer = LoadLibrary(str);
#endif
   }

   ~dll_file() {
      if(_pointer) {
#ifdef OS_WINDOWS
         CloseHandle(_pointer);
#endif
#ifdef OS_UNIX
         dlclose(_pointer);
#endif
      }
   }

   void close() {
      if(_pointer) {
#ifdef OS_WINDOWS
         CloseHandle(_pointer);
#endif
#ifdef OS_UNIX
         dlclose(_pointer);
#endif
         _pointer = 0;
      }
   }

   operator void*() {
      return _pointer;
   }

#ifdef OS_WINDOWS
   pf_t get_symbol(const char * symbol) {
      return get_proc_address(_pointer, symbol);
#endif
#ifdef OS_UNIX
   void * get_symbol(const char * symbol) {
      return dlsym(_pointer, symbol);
#endif
   }
};

#endif /* _DLL_FILE_H */
