text: //#BLITZ_APPROVE
  
  #define DLISTR__(s) #s
  #define DLISTR_(s)  DLISTR__(s)
  #define DLISTR(s)   DLISTR_(s)
  
  #define FN(retval, fn, args)           FN_CN(retval, DLLCALL, fn, args, DLISTR(fn))
  #define FN_C(retval, call, fn, args)   FN_CN(retval, call, fn, args, DLISTR(fn))
  #define FN_N(retval, fn, args, name)   FN_CN(retval, DLLCALL, fn, args, name)
  
  #define FN0(retval, fn, args)          FN0_CN(retval, DLLCALL, fn, args, DLISTR(fn))
  #define FN0_C(retval, call, fn, args)  FN0_CN(retval, call, fn, args, DLISTR(fn))
  #define FN0_N(retval, fn, args, name)  FN0_CN(retval, DLLCALL, fn, args, name)
  
  #ifndef DLLTYPE
  #define DLLTYPE   COMBINE(T_, DLIMODULE)
  #endif
  
  #ifndef DLLCALL
  #ifdef PLATFORM_WIN32
  #define DLLCALL //__cdecl
  #else
  #define DLLCALL
  #endif
  #endif
  
  #ifndef DLLSTRUCT
  #define DLLSTRUCT DLIMODULE
  #endif
  
  // ---------
  
  #if !defined(DLI_HEADER) && !defined(DLI_SOURCE)
  #define DLI_HEADER
  #define DLI_SOURCE
  #endif
  
  #ifdef DLI_HEADER
  #undef DLI_HEADER
  
  #define FN_CN(retval, call, fn, args, name)\
  	typedef retval (call fn##_type) args; fn##_type *fn;
  #define FN0_CN FN_CN
  
  struct DLLTYPE{
  	DLLTYPE();
  
  	UPP::String       GetLibName() const        { return libname; }
  	void              SetLibName(const char *n) { if(handle) Free(); libname = n; checked = false; }
  
  	bool              Load();
  	bool              Load(const char *n)       { SetLibName(n); return Load(); }
  	void              Force();
  	void              Free();
  
  	operator          bool ()      { return handle; }
  
  #include DLIHEADER
  private:
  	UPP::String       libname;
  	DLLHANDLE         handle;
  	bool              checked;
  };
  
  #undef FN_CN
  #undef FN0_CN
  
  // ---------
  
  DLLTYPE& DLIMODULE();
  DLLTYPE& COMBINE(DLIMODULE, _)();
  
  #endif
  
  #ifdef DLI_SOURCE
  #undef DLI_SOURCE
  
  DLLTYPE& COMBINE(DLIMODULE, _)()
  {
  	static DLLTYPE out;
  	return out;
  }
  
  DLLTYPE& DLIMODULE()
  {
  	DLLTYPE& out = COMBINE(DLIMODULE, _)();
  	out.Load();
  	return out;
  }
  
  DLLTYPE::DLLTYPE()
  {
  	checked = false;
  	handle = 0;
  	libname =
  #ifdef DLLFILENAME
  		DLLFILENAME;
  #else
  		DLISTR(DLLSTRUCT);
  #endif
  }
  
  bool DLLTYPE::Load()
  {
  	if(!checked)
  	{
  		checked = true;
  
  #define FN_CN(retval, call, fn, args, name)  name,
  #define FN0_CN(retval, call, fn, args, name) "?" name,
  
  		const char *name[] =
  		{
  		#include DLIHEADER
  			0
  		};
  
  #undef FN_CN
  #undef FN0_CN
  
  // --- FnPtr map
  
  
  #define FN_CN(retval, call, fn, args, name)  &fn,
  #define FN0_CN FN_CN
  
  		void *proc[] =
  		{
  		#include DLIHEADER
  			0
  		};
  
  #undef FN_CN
  #undef FN0_CN
  
  		// --- Proc pointers
  
  
  //		if(handle = LoadDll(file, name, proc))
  //			atexit(&Free);
  		handle = LoadDll__(libname, name, proc);
  	}
  	return handle;
  }
  
  void DLLTYPE::Force()
  {
  	if(!DLLTYPE::Load()) {
  //		RLOG("Failed to load required dynamic library '" << LibName() << "'");
  		exit(1);
  	}
  }
  
  void DLLTYPE::Free() {
  	if(handle) {
  		FreeDll__(handle);
  		handle = 0;
  	}
  	checked = false;
  }
  #endif
  
  #undef FN
  #undef FN_C
  #undef FN_N
  
  #undef FN0
  #undef FN0_C
  #undef FN0_N
  
  #undef DLISTR__
  #undef DLISTR_
  #undef DLISTR
  
  #ifdef DLLFILENAME
  #undef DLLFILENAME
  #endif
  
  #ifdef DLLAUTOLOAD
  #undef DLLAUTOLOAD
  #endif
  
  #undef DLLTYPE
  #undef DLIMODULE
  #undef DLIHEADER
  #undef DLLCALL
  
  #ifdef DLLFILENAME
  #undef DLLFILENAME
  #endif
  
  #ifdef DLLAUTOLOAD
  #undef DLLAUTOLOAD
  #endif
  