source: Sophya/trunk/SophyaLib/SysTools/pdlmgr.cc@ 2599

Last change on this file since 2599 was 2598, checked in by ansari, 21 years ago

Documentation (ajoutee ou completee) pour les classes du module SysTools - Reza 11 Aout 2004

File size: 9.2 KB
RevLine 
[1371]1//
[219]2// Gestionnaire de lien dynamique - R. Ansari 12/98
3// LAL (Orsay) / IN2P3-CNRS DAPNIA/SPP (Saclay) / CEA
[1371]4//
[1783]5#include <machdefs.h>
[219]6
[913]7#include "pdlmgr.h"
[219]8#include <stdio.h>
9#include <stdlib.h>
10
[2322]11#include <iostream>
[219]12
13
14// Extension de noms de fichiers Shared libs
15static const char* sofext = ".so";
16static const char* sofext_HPUX = ".sl";
[1900]17// static const char* sofext_Darwin = ".dylib"; pas necessaire - Reza 02/2002
[219]18
19// Variables et methodes static
20int PDynLinkMgr::numSO = 0;
21string* PDynLinkMgr::tmpDir = NULL;
22
[895]23/*!
24 \class SOPHYA::PDynLinkMgr
[913]25 \ingroup SysTools
[895]26 This classes handles the run-time operations related to using shared
27 libraries. The present version has been adapted for different Unix
[2598]28 flavours (Linux, HP/Compaq/Digital OSF-Tru64, SGI IRIX, IBM AIX, Sun Solaris,
29 MacOS X/Darwin). \n
30 For MacOS X/Darwin, the NSxxx API
31 <tt> (NSLinkModule , NSCreateObjectFileImageFromFile, ...) </tt>
32 is used.
[1275]33 The example here shows the linking of shared library named "mylib.so"
[913]34 containing a function \c double \c myfunction(double x).
35 \code
36 #include "pdlmgr.h"
37 typedef double (* AFunctionOfX) (double x);
38 {
39 // ...
40 string soname = "mylib.so";
41 string funcname = "myfunction";
42 PDynLinkMgr dyl(son);
43 AFunctionOfX f = (AFunctionOfX)dyl.GetFunction(funcname);
44 double x = 3.1425;
45 if (f != NULL)
46 cout << " X= " << x << " myfunction(x)=" << f(x) << endl;
47 // ...
48 }
49 \endcode
[895]50*/
51
[219]52/* --Methode-Static-- */
[895]53/*! Sets the path for a temporary space where shared libraries are copied.
54 The path is appended to \b LD_LIBRARY_PATH
55*/
[219]56void PDynLinkMgr::SetTmpDir(string const & path)
57{
[1275]58if ( (path.length() > 0) && (path[path.length()-1] != '/') ) GetTmpDir() = path + '/';
[219]59else GetTmpDir() = path;
[1275]60#if defined(OSF1) || defined(Linux) || defined(SunOS) || defined(IRIX64)
61 char* varenv=NULL;
62#if !defined(IRIX64)
[480]63 string cmd = "LD_LIBRARY_PATH=";
64 varenv=getenv("LD_LIBRARY_PATH");
[1275]65#else
66#ifdef SGI_ARCH64
[480]67 string cmd = "LD_LIBRARYN32_PATH=";
68 varenv=getenv("LD_LIBRARYN32_PATH");
[1275]69#else
70 string cmd = "LD_LIBRARYN64_PATH=";
71 varenv=getenv("LD_LIBRARYN64_PATH");
72#endif
73#endif
[480]74
75 if (varenv == NULL) {
76 cmd += '.';
77 if (path.length() > 0) cmd += ':' + path;
78 }
79 else {
80 if (varenv[0] != '.') cmd += ".:";
81 if (path.length() > 0) cmd += path + ':';
82 cmd += varenv;
[1294]83 putenv(const_cast<char *>(cmd.c_str()));
[480]84 }
85#elif defined(AIX)
86 string cmd = "LIBPATH=";
87 char* varenv=NULL;
88 varenv=getenv("LIBPATH");
89 if (varenv == NULL) {
90 cmd += '.';
91 if (path.length() > 0) cmd += ':' + path;
92 cmd += ":/usr/lib:/lib";
93 }
94 else {
95 if (varenv[0] != '.') cmd += ".:";
96 if (path.length() > 0) cmd += path + ':';
97 cmd += varenv;
98 putenv(const_cast<char *>(cmd.c_str()));
99 }
100
101#endif
[219]102return;
103}
104
105/* --Methode-Static-- */
[895]106/*! Returns the temporary space path */
[219]107string& PDynLinkMgr::GetTmpDir()
108{
109if (tmpDir == NULL) {
110 tmpDir = new string("");
111 char* varenv;
[1277]112 if ( (varenv=getenv("TMPDIR")) != NULL ) {
113 *tmpDir = varenv;
114 if ((*tmpDir)[tmpDir->length()-1] != '/') (*tmpDir) += '/';
[219]115 }
[1277]116}
[219]117return(*tmpDir);
118}
119
120/* --Methode-Static-- */
[895]121/*! Compiles the C source file named \b fname and creates the
122 corresponding shared library linking against the standard
123 C library (-lc) and the math library (-lm).
124 Returns a pointer to the created PDynLinkMgr object (by new).
125 Returns the NULL pointer in case of errors.
126*/
[219]127PDynLinkMgr* PDynLinkMgr::BuildFromCFile(string const & fname)
128{
129size_t l = fname.length();
130if (l < 1) return(NULL);
131string fnameobj = GetTmpDir()+"tmp_pdl.o";
132
133string cmd;
134int rc;
135
136// Compilation du fichier
[480]137#ifndef __mac__
[1249]138#ifdef SGI_ARCH64
139cmd = "cc -64 -c -o " + fnameobj + " " + fname;
140#else
[219]141cmd = "cc -c -o " + fnameobj + " " + fname;
[1249]142#endif
[480]143#else
144cmd = "Il faut compiler !!!" + fnameobj + " " + fname;
[219]145#endif
146rc = system(cmd.c_str());
147if (rc != 0) {
148 cerr << "PDynLinkMgr::BuildFromCFile() Error Rc(" << cmd <<")= "<< rc << endl;
149 return(NULL);
150 }
151
152char buff[32];
153numSO++;
154#ifndef HPUX
155sprintf(buff,"pdlmgr%d%s", numSO,sofext);
156#endif
157string fnameso = GetTmpDir()+buff;
158
159// Creation du shared-lib
160#if defined(OSF1)
161 cmd = "ld -shared -o " + fnameso + " -all " + fnameobj + " -none -lm -lc";
[480]162#elif defined(Linux)
[219]163 cmd = "ld -shared -o " + fnameso + " " + fnameobj + " -lm -lc";
[480]164#elif defined(SunOS)
165 cmd = "ld -G -o " + fnameso + " " + fnameobj + " -lm -lc";
166#elif defined(IRIX64)
[1249]167#ifdef SGI_ARCH64
168 cmd = "ld -64 -shared -o " + fnameso + " " + fnameobj + " -lm -lc";
169#else
[480]170 cmd = "ld -shared -o " + fnameso + " " + fnameobj + " -lm -lc";
[1249]171#endif
[480]172#elif defined(AIX)
173 cmd = "ld -G -bnogc -bexpall -bM:1L -o " + fnameso + " " + fnameobj;
174#elif defined(HPUX)
175 cmd = "ld -b -o " + fnameso + " " + fnameobj + " -lm -lc";
[1795]176#elif defined(Darwin)
[2496]177 // cmd = "cc -bundle -flat_namespace -undefined suppress -o " + fnameso + " " + fnameobj + " -lm -lcc_dynamic -lSystem ";
178 cmd = "cc -bundle -o " + fnameso + " " + fnameobj + " -lSystem -lm";
[480]179#else
180 cmd = "ld -o " + fnameso + " " + fnameobj + " -lm -lc";
[219]181#endif
182rc = system(cmd.c_str());
183if (rc != 0) {
184 cerr << "PDynLinkMgr::BuildFromCFile() Error Rc(" << cmd <<")= "<< rc << endl;
185 return(NULL);
186 }
[296]187PDynLinkMgr* rdyn = new PDynLinkMgr(fnameso, false);
188rdyn->copy = true;
189return(rdyn);
[219]190
191}
192
193/* --Methode-- */
[895]194/*! The constructor.
195 \param soname : Name of the shared library. ".so" is appended
196 to the name if no dot "." is found in the name.
197 \param cp : if true, copies the shared library in the temporary space.
198*/
[219]199PDynLinkMgr::PDynLinkMgr(string& soname, bool cp)
200{
[2496]201dylok = false;
[219]202soName = "";
203
204if (soname.find_last_of(".") > soname.length())
205#ifdef HPUX
206 soname += sofext_HPUX;
207#else
208 soname += sofext;
209#endif
210
211string fnameso;
212if (cp) {
213 numSO++;
214 char buff[32];
215#ifndef HPUX
216 sprintf(buff,"pdlmgr%d%s", numSO,sofext);
[1795]217#elif defined(Darwin)
218 sprintf(buff,"pdlmgr%d%s", numSO,sofext_Darwin);
[219]219#else
220 sprintf(buff,"pdlmgr%d%s", numSO,sofext_HPUX);
221#endif
222 fnameso = GetTmpDir()+buff;
223 string cmd = "cp " + soname + " " + fnameso;
224 int rc = system(cmd.c_str());
225 if (rc != 0) {
226 cerr << "PDynLinkMgr::PDynLinkMgr() Error Rc(" << cmd <<")= "<< rc << endl;
227 return;
228 }
229 }
230else fnameso = soname;
231copy = cp;
232soName = fnameso;
233
[2496]234string sdylerr;
[480]235#if defined(HPUX)
236cerr << "PDynLinkMgr::PDynLinkMgr() Not yet available on HP-UX " << endl;
237return;
[2496]238#elif defined(Darwin)
239NSObjectFileImageReturnCode nsrc = NSCreateObjectFileImageFromFile(fnameso.c_str(), &nsobjfile);
240if (nsrc == NSObjectFileImageSuccess) {
241 nsmod = NSLinkModule(nsobjfile, fnameso.c_str(),
242 NSLINKMODULE_OPTION_BINDNOW | NSLINKMODULE_OPTION_PRIVATE |
243 NSLINKMODULE_OPTION_RETURN_ON_ERROR);
244 // The second argument of NSLinkModule is the module name
245 // We might associate later a name for the module in the PDynLinkMgr object
246 if (nsmod != NULL) dylok = true;
247 else cerr << "PDynLinkMgr::PDynLinkMgr()/ Error from NSLinkModule ... " << endl;
248}
249else {
250 cerr << "PDynLinkMgr::PDynLinkMgr()/ Error from NSCreateObjectFileImageFromFile ... " << endl;
251 if (nsrc == NSObjectFileImageFailure) cerr << " ErrCode= NSObjectFileImageFailure " << endl;
252 else if (nsrc == NSObjectFileImageInappropriateFile) cerr << " ErrCode= NSObjectFileImageInappropriateFile" << endl;
253 else if (nsrc == NSObjectFileImageArch ) cerr << " ErrCode= NSObjectFileImageArch" << endl;
254 else if (nsrc == NSObjectFileImageFormat) cerr << " ErrCode= NSObjectFileImageFormat" << endl;
255 else if (nsrc == NSObjectFileImageAccess) cerr << " ErrCode= NSObjectFileImageAccess" << endl;
[2498]256 }
[480]257#else
[2496]258dlhandle = NULL;
[219]259dlhandle = dlopen(fnameso.c_str(), RTLD_NOW);
[2496]260if (dlhandle != NULL) dylok = true;
261else {
262 sdylerr = "Loader Error (dlerror()):";
263 sdylerr += dlerror();
[2498]264 }
[2496]265#endif
266
267if (!dylok) {
[219]268 cerr << "PDynLinkMgr::PDynLinkMgr(): Error opening SO " << fnameso
269 << " (" << soname << ")" << endl;
[2496]270 if (sdylerr.length() > 0) cerr << sdylerr;
[219]271 return;
272 }
273}
274
275/* --Methode-- */
[895]276/*! Destructor. Closes the shared library. Removes the file if it had been
277 copied in the temporary space, or generated by \b BuildFromCFile */
[219]278PDynLinkMgr::~PDynLinkMgr()
279{
[480]280#if defined(HPUX)
281cerr << "PDynLinkMgr::~PDynLinkMgr() Not yet available on HP-UX " << endl;
[2496]282// return;
283#elif defined(Darwin)
284if (dylok) {
285 if (nsmod != NULL) NSUnLinkModule(nsmod, NSUNLINKMODULE_OPTION_NONE);
286 NSDestroyObjectFileImage(nsobjfile);
287 }
[480]288#else
[2496]289if (dylok) {
290 if (dlhandle) dlclose(dlhandle); dlhandle = NULL;
291 }
292#endif
[219]293if (copy) {
[296]294 string cmd = "rm -f " + soName;
[219]295 system(cmd.c_str());
296 }
297}
298
299/* --Methode-- */
[895]300/*! Returns a handle to the function named \b funcname.
301 Returns the NULL pointer in case of error */
[219]302DlFunction PDynLinkMgr::GetFunction(string const & funcname)
303{
304DlFunction f = NULL;
[2496]305if (!dylok) {
306 cerr << "PDynLinkMgr::GetFunction() Error:sharedobjet/dynamic library not open -> f=NULL" << endl;
307 return f;
308}
[480]309#if defined(HPUX)
310cerr << "PDynLinkMgr::GetFunction() Not yet available on HP-UX " << endl;
311return f;
[2496]312#endif
[1900]313#if defined(Darwin)
314string funame = "_" + funcname;
[2496]315NSSymbol nsf = NSLookupSymbolInModule(nsmod, funame.c_str());
316f = (DlFunction)NSAddressOfSymbol(nsf);
[1900]317#else
[1902]318string const & funame = funcname;
[219]319if (dlhandle != NULL)
[1900]320 f = (DlFunction)dlsym(dlhandle, funame.c_str());
[2496]321#endif
322
[480]323if (f == NULL) cerr << "PDynLinkMgr::GetFunction(): Error linking " << funcname << endl;
324return(f);
[219]325}
326
[1795]327
Note: See TracBrowser for help on using the repository browser.