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

Last change on this file since 1364 was 1294, checked in by ansari, 25 years ago

const_cast<char *> pour putenv() , Reza+cmv , 6/11/2000

File size: 6.9 KB
Line 
1// Gestionnaire de lien dynamique - R. Ansari 12/98
2// LAL (Orsay) / IN2P3-CNRS DAPNIA/SPP (Saclay) / CEA
3
4#include "pdlmgr.h"
5#include <stdio.h>
6#include <stdlib.h>
7
8#include <iostream.h>
9
10
11// Extension de noms de fichiers Shared libs
12static const char* sofext = ".so";
13static const char* sofext_HPUX = ".sl";
14
15// Variables et methodes static
16int PDynLinkMgr::numSO = 0;
17string* PDynLinkMgr::tmpDir = NULL;
18
19/*!
20 \class SOPHYA::PDynLinkMgr
21 \ingroup SysTools
22 This classes handles the run-time operations related to using shared
23 libraries. The present version has been adapted for different Unix
24 flavours (Linux, Compaq/Digital Unix, SGI IRIX, IBM AIX, Sun Solaris).
25 The example here shows the linking of shared library named "mylib.so"
26 containing a function \c double \c myfunction(double x).
27 \code
28 #include "pdlmgr.h"
29 typedef double (* AFunctionOfX) (double x);
30 {
31 // ...
32 string soname = "mylib.so";
33 string funcname = "myfunction";
34 PDynLinkMgr dyl(son);
35 AFunctionOfX f = (AFunctionOfX)dyl.GetFunction(funcname);
36 double x = 3.1425;
37 if (f != NULL)
38 cout << " X= " << x << " myfunction(x)=" << f(x) << endl;
39 // ...
40 }
41 \endcode
42*/
43
44/* --Methode-Static-- */
45/*! Sets the path for a temporary space where shared libraries are copied.
46 The path is appended to \b LD_LIBRARY_PATH
47*/
48void PDynLinkMgr::SetTmpDir(string const & path)
49{
50if ( (path.length() > 0) && (path[path.length()-1] != '/') ) GetTmpDir() = path + '/';
51else GetTmpDir() = path;
52#if defined(OSF1) || defined(Linux) || defined(SunOS) || defined(IRIX64)
53 char* varenv=NULL;
54#if !defined(IRIX64)
55 string cmd = "LD_LIBRARY_PATH=";
56 varenv=getenv("LD_LIBRARY_PATH");
57#else
58#ifdef SGI_ARCH64
59 string cmd = "LD_LIBRARYN32_PATH=";
60 varenv=getenv("LD_LIBRARYN32_PATH");
61#else
62 string cmd = "LD_LIBRARYN64_PATH=";
63 varenv=getenv("LD_LIBRARYN64_PATH");
64#endif
65#endif
66
67 if (varenv == NULL) {
68 cmd += '.';
69 if (path.length() > 0) cmd += ':' + path;
70 }
71 else {
72 if (varenv[0] != '.') cmd += ".:";
73 if (path.length() > 0) cmd += path + ':';
74 cmd += varenv;
75 putenv(const_cast<char *>(cmd.c_str()));
76 }
77#elif defined(AIX)
78 string cmd = "LIBPATH=";
79 char* varenv=NULL;
80 varenv=getenv("LIBPATH");
81 if (varenv == NULL) {
82 cmd += '.';
83 if (path.length() > 0) cmd += ':' + path;
84 cmd += ":/usr/lib:/lib";
85 }
86 else {
87 if (varenv[0] != '.') cmd += ".:";
88 if (path.length() > 0) cmd += path + ':';
89 cmd += varenv;
90 putenv(const_cast<char *>(cmd.c_str()));
91 }
92
93#endif
94return;
95}
96
97/* --Methode-Static-- */
98/*! Returns the temporary space path */
99string& PDynLinkMgr::GetTmpDir()
100{
101if (tmpDir == NULL) {
102 tmpDir = new string("");
103 char* varenv;
104 if ( (varenv=getenv("TMPDIR")) != NULL ) {
105 *tmpDir = varenv;
106 if ((*tmpDir)[tmpDir->length()-1] != '/') (*tmpDir) += '/';
107 }
108}
109return(*tmpDir);
110}
111
112/* --Methode-Static-- */
113/*! Compiles the C source file named \b fname and creates the
114 corresponding shared library linking against the standard
115 C library (-lc) and the math library (-lm).
116 Returns a pointer to the created PDynLinkMgr object (by new).
117 Returns the NULL pointer in case of errors.
118*/
119PDynLinkMgr* PDynLinkMgr::BuildFromCFile(string const & fname)
120{
121size_t l = fname.length();
122if (l < 1) return(NULL);
123string fnameobj = GetTmpDir()+"tmp_pdl.o";
124
125string cmd;
126int rc;
127
128// Compilation du fichier
129#ifndef __mac__
130#ifdef SGI_ARCH64
131cmd = "cc -64 -c -o " + fnameobj + " " + fname;
132#else
133cmd = "cc -c -o " + fnameobj + " " + fname;
134#endif
135#else
136cmd = "Il faut compiler !!!" + fnameobj + " " + fname;
137#endif
138rc = system(cmd.c_str());
139if (rc != 0) {
140 cerr << "PDynLinkMgr::BuildFromCFile() Error Rc(" << cmd <<")= "<< rc << endl;
141 return(NULL);
142 }
143
144char buff[32];
145numSO++;
146#ifndef HPUX
147sprintf(buff,"pdlmgr%d%s", numSO,sofext);
148#endif
149string fnameso = GetTmpDir()+buff;
150
151// Creation du shared-lib
152#if defined(OSF1)
153 cmd = "ld -shared -o " + fnameso + " -all " + fnameobj + " -none -lm -lc";
154#elif defined(Linux)
155 cmd = "ld -shared -o " + fnameso + " " + fnameobj + " -lm -lc";
156#elif defined(SunOS)
157 cmd = "ld -G -o " + fnameso + " " + fnameobj + " -lm -lc";
158#elif defined(IRIX64)
159#ifdef SGI_ARCH64
160 cmd = "ld -64 -shared -o " + fnameso + " " + fnameobj + " -lm -lc";
161#else
162 cmd = "ld -shared -o " + fnameso + " " + fnameobj + " -lm -lc";
163#endif
164#elif defined(AIX)
165 cmd = "ld -G -bnogc -bexpall -bM:1L -o " + fnameso + " " + fnameobj;
166#elif defined(HPUX)
167 cmd = "ld -b -o " + fnameso + " " + fnameobj + " -lm -lc";
168#else
169 cmd = "ld -o " + fnameso + " " + fnameobj + " -lm -lc";
170#endif
171rc = system(cmd.c_str());
172if (rc != 0) {
173 cerr << "PDynLinkMgr::BuildFromCFile() Error Rc(" << cmd <<")= "<< rc << endl;
174 return(NULL);
175 }
176PDynLinkMgr* rdyn = new PDynLinkMgr(fnameso, false);
177rdyn->copy = true;
178return(rdyn);
179
180}
181
182/* --Methode-- */
183/*! The constructor.
184 \param soname : Name of the shared library. ".so" is appended
185 to the name if no dot "." is found in the name.
186 \param cp : if true, copies the shared library in the temporary space.
187*/
188PDynLinkMgr::PDynLinkMgr(string& soname, bool cp)
189{
190dlhandle = NULL;
191soName = "";
192
193if (soname.find_last_of(".") > soname.length())
194#ifdef HPUX
195 soname += sofext_HPUX;
196#else
197 soname += sofext;
198#endif
199
200string fnameso;
201if (cp) {
202 numSO++;
203 char buff[32];
204#ifndef HPUX
205 sprintf(buff,"pdlmgr%d%s", numSO,sofext);
206#else
207 sprintf(buff,"pdlmgr%d%s", numSO,sofext_HPUX);
208#endif
209 fnameso = GetTmpDir()+buff;
210 string cmd = "cp " + soname + " " + fnameso;
211 int rc = system(cmd.c_str());
212 if (rc != 0) {
213 cerr << "PDynLinkMgr::PDynLinkMgr() Error Rc(" << cmd <<")= "<< rc << endl;
214 return;
215 }
216 }
217else fnameso = soname;
218copy = cp;
219soName = fnameso;
220
221#if defined(HPUX)
222dlhandle = NULL;
223cerr << "PDynLinkMgr::PDynLinkMgr() Not yet available on HP-UX " << endl;
224return;
225#else
226dlhandle = dlopen(fnameso.c_str(), RTLD_NOW);
227if (dlhandle == NULL) {
228 cerr << "PDynLinkMgr::PDynLinkMgr(): Error opening SO " << fnameso
229 << " (" << soname << ")" << endl;
230 string sn = dlerror();
231 cerr << "Loader Error (dlerror()) :" << sn << endl;
232 return;
233 }
234#endif
235}
236
237/* --Methode-- */
238/*! Destructor. Closes the shared library. Removes the file if it had been
239 copied in the temporary space, or generated by \b BuildFromCFile */
240PDynLinkMgr::~PDynLinkMgr()
241{
242#if defined(HPUX)
243cerr << "PDynLinkMgr::~PDynLinkMgr() Not yet available on HP-UX " << endl;
244return;
245#else
246if (dlhandle) dlclose(dlhandle); dlhandle = NULL;
247if (copy) {
248 string cmd = "rm -f " + soName;
249 system(cmd.c_str());
250 }
251#endif
252}
253
254/* --Methode-- */
255/*! Returns a handle to the function named \b funcname.
256 Returns the NULL pointer in case of error */
257DlFunction PDynLinkMgr::GetFunction(string const & funcname)
258{
259DlFunction f = NULL;
260#if defined(HPUX)
261cerr << "PDynLinkMgr::GetFunction() Not yet available on HP-UX " << endl;
262return f;
263#else
264if (dlhandle != NULL)
265 f = (DlFunction)dlsym(dlhandle, funcname.c_str());
266if (f == NULL) cerr << "PDynLinkMgr::GetFunction(): Error linking " << funcname << endl;
267return(f);
268#endif
269}
270
Note: See TracBrowser for help on using the repository browser.