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

Last change on this file since 989 was 913, checked in by ansari, 25 years ago

Documentation + Modifs mineures (namespace, etc..) - Reza 13/4/2000

File size: 6.6 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 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()] != '/') ) GetTmpDir() = path + '/';
51else GetTmpDir() = path;
52#if defined(OSF1) || defined(Linux) || defined(SunOS)
53 string cmd = "LD_LIBRARY_PATH=";
54 char* varenv=NULL;
55 varenv=getenv("LD_LIBRARY_PATH");
56#elif defined(IRIX64)
57 string cmd = "LD_LIBRARYN32_PATH=";
58 char* varenv=NULL;
59 varenv=getenv("LD_LIBRARYN32_PATH");
60
61 if (varenv == NULL) {
62 cmd += '.';
63 if (path.length() > 0) cmd += ':' + path;
64 }
65 else {
66 if (varenv[0] != '.') cmd += ".:";
67 if (path.length() > 0) cmd += path + ':';
68 cmd += varenv;
69 putenv(cmd.c_str());
70 }
71#elif defined(AIX)
72 string cmd = "LIBPATH=";
73 char* varenv=NULL;
74 varenv=getenv("LIBPATH");
75 if (varenv == NULL) {
76 cmd += '.';
77 if (path.length() > 0) cmd += ':' + path;
78 cmd += ":/usr/lib:/lib";
79 }
80 else {
81 if (varenv[0] != '.') cmd += ".:";
82 if (path.length() > 0) cmd += path + ':';
83 cmd += varenv;
84 putenv(const_cast<char *>(cmd.c_str()));
85 }
86
87#endif
88return;
89}
90
91/* --Methode-Static-- */
92/*! Returns the temporary space path */
93string& PDynLinkMgr::GetTmpDir()
94{
95if (tmpDir == NULL) {
96 tmpDir = new string("");
97 char* varenv;
98 if ( (varenv=getenv("SOPHYA_TMP")) != NULL ) *tmpDir = varenv;
99 else if ( (varenv=getenv("TMPDIR")) != NULL ) *tmpDir = varenv;
100 }
101return(*tmpDir);
102}
103
104/* --Methode-Static-- */
105/*! Compiles the C source file named \b fname and creates the
106 corresponding shared library linking against the standard
107 C library (-lc) and the math library (-lm).
108 Returns a pointer to the created PDynLinkMgr object (by new).
109 Returns the NULL pointer in case of errors.
110*/
111PDynLinkMgr* PDynLinkMgr::BuildFromCFile(string const & fname)
112{
113size_t l = fname.length();
114if (l < 1) return(NULL);
115string fnameobj = GetTmpDir()+"tmp_pdl.o";
116
117string cmd;
118int rc;
119
120// Compilation du fichier
121#ifndef __mac__
122cmd = "cc -c -o " + fnameobj + " " + fname;
123#else
124cmd = "Il faut compiler !!!" + fnameobj + " " + fname;
125#endif
126rc = system(cmd.c_str());
127if (rc != 0) {
128 cerr << "PDynLinkMgr::BuildFromCFile() Error Rc(" << cmd <<")= "<< rc << endl;
129 return(NULL);
130 }
131
132char buff[32];
133numSO++;
134#ifndef HPUX
135sprintf(buff,"pdlmgr%d%s", numSO,sofext);
136#endif
137string fnameso = GetTmpDir()+buff;
138
139// Creation du shared-lib
140#if defined(OSF1)
141 cmd = "ld -shared -o " + fnameso + " -all " + fnameobj + " -none -lm -lc";
142#elif defined(Linux)
143 cmd = "ld -shared -o " + fnameso + " " + fnameobj + " -lm -lc";
144#elif defined(SunOS)
145 cmd = "ld -G -o " + fnameso + " " + fnameobj + " -lm -lc";
146#elif defined(IRIX64)
147 cmd = "ld -shared -o " + fnameso + " " + fnameobj + " -lm -lc";
148#elif defined(AIX)
149 cmd = "ld -G -bnogc -bexpall -bM:1L -o " + fnameso + " " + fnameobj;
150#elif defined(HPUX)
151 cmd = "ld -b -o " + fnameso + " " + fnameobj + " -lm -lc";
152#else
153 cmd = "ld -o " + fnameso + " " + fnameobj + " -lm -lc";
154#endif
155rc = system(cmd.c_str());
156if (rc != 0) {
157 cerr << "PDynLinkMgr::BuildFromCFile() Error Rc(" << cmd <<")= "<< rc << endl;
158 return(NULL);
159 }
160PDynLinkMgr* rdyn = new PDynLinkMgr(fnameso, false);
161rdyn->copy = true;
162return(rdyn);
163
164}
165
166/* --Methode-- */
167/*! The constructor.
168 \param soname : Name of the shared library. ".so" is appended
169 to the name if no dot "." is found in the name.
170 \param cp : if true, copies the shared library in the temporary space.
171*/
172PDynLinkMgr::PDynLinkMgr(string& soname, bool cp)
173{
174dlhandle = NULL;
175soName = "";
176
177if (soname.find_last_of(".") > soname.length())
178#ifdef HPUX
179 soname += sofext_HPUX;
180#else
181 soname += sofext;
182#endif
183
184string fnameso;
185if (cp) {
186 numSO++;
187 char buff[32];
188#ifndef HPUX
189 sprintf(buff,"pdlmgr%d%s", numSO,sofext);
190#else
191 sprintf(buff,"pdlmgr%d%s", numSO,sofext_HPUX);
192#endif
193 fnameso = GetTmpDir()+buff;
194 string cmd = "cp " + soname + " " + fnameso;
195 int rc = system(cmd.c_str());
196 if (rc != 0) {
197 cerr << "PDynLinkMgr::PDynLinkMgr() Error Rc(" << cmd <<")= "<< rc << endl;
198 return;
199 }
200 }
201else fnameso = soname;
202copy = cp;
203soName = fnameso;
204
205#if defined(HPUX)
206dlhandle = NULL;
207cerr << "PDynLinkMgr::PDynLinkMgr() Not yet available on HP-UX " << endl;
208return;
209#else
210dlhandle = dlopen(fnameso.c_str(), RTLD_NOW);
211if (dlhandle == NULL) {
212 cerr << "PDynLinkMgr::PDynLinkMgr(): Error opening SO " << fnameso
213 << " (" << soname << ")" << endl;
214 string sn = dlerror();
215 cerr << "Loader Error (dlerror()) :" << sn << endl;
216 return;
217 }
218#endif
219}
220
221/* --Methode-- */
222/*! Destructor. Closes the shared library. Removes the file if it had been
223 copied in the temporary space, or generated by \b BuildFromCFile */
224PDynLinkMgr::~PDynLinkMgr()
225{
226#if defined(HPUX)
227cerr << "PDynLinkMgr::~PDynLinkMgr() Not yet available on HP-UX " << endl;
228return;
229#else
230if (dlhandle) dlclose(dlhandle); dlhandle = NULL;
231if (copy) {
232 string cmd = "rm -f " + soName;
233 system(cmd.c_str());
234 }
235#endif
236}
237
238/* --Methode-- */
239/*! Returns a handle to the function named \b funcname.
240 Returns the NULL pointer in case of error */
241DlFunction PDynLinkMgr::GetFunction(string const & funcname)
242{
243DlFunction f = NULL;
244#if defined(HPUX)
245cerr << "PDynLinkMgr::GetFunction() Not yet available on HP-UX " << endl;
246return f;
247#else
248if (dlhandle != NULL)
249 f = (DlFunction)dlsym(dlhandle, funcname.c_str());
250if (f == NULL) cerr << "PDynLinkMgr::GetFunction(): Error linking " << funcname << endl;
251return(f);
252#endif
253}
254
Note: See TracBrowser for help on using the repository browser.