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

Last change on this file since 2496 was 2496, checked in by ansari, 22 years ago

Implementation propre de la gestion de chargement dynamique (classe PDynLinkMgr) sur MacOSX/Darwin a travers les API NSObjectFileImage et NSModule + petite correction ds zthread.h (deplacement de unlock()) - Reza 3 Fevrier 2004

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