//-----------------------------------------------------------------------------
// Copyright (c) 1994,1995 Southeastern Universities Research Association,
//                         Continuous Electron Beam Accelerator Facility
//
// This software was developed under a United States Government license
// described in the NOTICE file included as part of this distribution.
//
//-----------------------------------------------------------------------------
// 
// Description:
//	 shObjLoader class (for hp ,sun (SunOs 4.x) , sgi (irix),
//       solaris 2.x and linux only)
//	
// Author:  Jie Chen
//
// Revision History:
//   shObjLoader.h,v
// Revision 1.6  1996/03/22  16:32:09  chen
// support solaris
//
// Revision 1.5  1995/11/14  17:35:17  chen
// better header
//
// Revision 1.4  1995/11/14  17:33:37  chen
// fix to work under irix5.3
//
// Revision 1.3  1995/10/18  17:45:06  chen
// To work under SunOs
//
// Revision 1.2  1995/10/17  13:25:18  chen
// Change load (int flag) to load (void)
//
// Revision 1.1.1.1  1995/06/16  17:14:02  epics
// initial import of cdev
//
//
#ifndef _SH_OBJ_LOADER_H
#define _SH_OBJ_LOADER_H

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

#ifdef __hpux 
	#ifdef _CENTERLINE
		#include <dl.h>
		#define HP_SHOBJ_LOADER   ::shl_load
		#define HP_SHOBJ_UNLOADER ::shl_unload
	#elif (_OS_MAJOR==9 || (_OS_MAJOR==10 && _OS_MINOR==10))
		#include <cxxdl.h>
		#define HP_SHOBJ_LOADER   ::cxxshl_load
		#define HP_SHOBJ_UNLOADER ::cxxshl_unload
	#else
		#include <dl.h>
		#define HP_SHOBJ_LOADER   ::shl_load
		#define HP_SHOBJ_UNLOADER ::shl_unload
	#endif
#endif

#ifdef sunos4
// sun header file dlfunc.h is not defined for cplusplus
extern "C"
{
void *dlopen  (char* path, int mode);
void *dlsym   (void* handle, char* symbol);
char *dlerror (void);
int   dlclose (void* handle);
};
#define RTLD_LAZY 1
#endif

#if defined (sgi) || defined (solaris) || defined (aix) || defined (__linux)
#include <dlfcn.h>
#endif

#if defined (_WIN32)
#include <windows.h>

#ifndef SHOBJ
#define SHOBJ 1
#endif

#endif

#include <errno.h>

class shObjLoader
{
public:
  //constructors and destructor
  shObjLoader          (char *path);
  virtual ~shObjLoader (void);

  virtual int open (char *name);
  // PURPOSE: open a shared library by a given name
  // REQUIRE: name != 0
  // PROMISE: library path name will be stored

  virtual int load (void);
  // PURPOSE: load a shared library in verbose mode if possible
  // REQUIRE: call open first
  // PROMISE: return 0: success loaded. return -1: load failed

  virtual int findProcedureSym (const char * sym, void** value);
  // PURPOSE: find procedure address given by symbol
  // REQUIRE: call load first
  // PROMISE: value will be the address. return 0: success, -1: failure

#ifdef __hpux
  virtual int findDataSym      (const char * sym, void * value);
  // PURPOSE: find data address given by symbol
  // REQUIRE: call load first
  // PROMISE: value will be the address

  virtual int findSym          (const char * sym, void * value);
  // PURPOSE: find address given by symbol
  // REQUIRE: call load first
  // PROMISE: value will be the address. return 0: success, -1: failure
  
  unsigned long textStartAddr (void);
  // PURPOSE: find text section start address
  // REQUIRE: call load first
  // PROMISE: return address, 0: failure

  unsigned long textEndAddr (void);
  // PURPOSE: find text section end address
  // REQUIRE: call load first
  // PROMISE: return address, 0: failure

  unsigned long dataStartAddr (void);
  // PURPOSE: find data section start address
  // REQUIRE: call load first
  // PROMISE: return address, 0: failure

  unsigned long dataEndAddr (void);
  // PURPOSE: find data section end address
  // REQUIRE: call load first
  // PROMISE: return address, 0: failure
#endif // end __hpux

  const char *filename (void);
  // PURPOSE: loaded shared library path name
  // REQUIRE: nothing
  // PROMISE: 0: means nothing loaded

  virtual int close (void);
  // PURPOSE: remove shared library from memory
  // REQUIRE: nothing
  // PROMISE: Shared library will be removed from memory
  //          filename () return 0
  
  virtual const char *className (void) const {return "shObjLoader";}

private:
#ifdef __hpux
  shl_t  libHandler_;
  struct shl_descriptor *desc_;
#endif // endif __hpux

#if defined (sunos4) || defined (sgi) || defined (solaris) || defined (aix) || defined (__linux)
  void* libHandler_;
#endif // endif sun or sgi

#if defined (_WIN32)
  HINSTANCE libHandler_;
#endif

  char   *libName_;
};
#endif
