Hi, I am searching for a way to solve the following problem: I want to use an external function, defined in a dyn.load()ed shared object, in another dyn.load()ed shared object. Currently I have to take the sources (Fortran) from one libraries src/ directory and copy them into the src/ dir of the other library, resulting in two copies of this function. This is bad for maintanance and maybe also for runtime behaviour because of side effects I'm not aware off (one symbol could be loaded twice). It would be nice if I could call the function directly from C/Fortran, after dyn.load()ing both libraries. But unfortunately this seems to depend very crucially on the specific OS. An example (C/Fortran mix, but I tried also C/C and Fortran/Fortran): **** so1.c ******************* #include <R.h> void func1(double* a, int* n){ printf("in func1\n"); F77_SYMBOL(func2)(a,n); printf("back in func1\n"); } ****************************** gcc -g -fpic -c so1.c -I/usr/local/lib/R/include ld -shared so1.o -o so1.so **** so2.f ******************* subroutine func2(a,n) real*8 a(*) integer n integer i call intpr("in func2",8,0,0) do 10 i=1,n a(i)=2.0d0 * a(i) 10 continue return end ****************************** g77 -g -fpic -c so2.f ld -shared so2.o -o so2.so on the Alpha (R 1.1.0 on alpha-dec-osf4.0) it works without problems:> dyn.load("so2.so") > dyn.load("so1.so") > .C("func1",as.double(c(1,2,3)),as.integer(3))in func1 in func2 [1] back in func1 [[1]] [1] 2 4 6 [[2]] [1] 3 on Linux (R 1.1.1, SuSE 6.4) it works not:> dyn.load("so2.so") > dyn.load("so1.so")Error in dyn.load(x, as.logical(local), as.logical(now)) : unable to load shared library "/home/users/agebhard/R-test/so1.so": /home/users/agebhard/R-test/so1.so: undefined symbol: func2_ or also not working:> dyn.load("so2.so") > dyn.load("so1.so",now=F) > .C("func1",as.double(c(1,2,3)),as.integer(3))in func1 /usr/lib/R/bin/R.bin: error in loading shared libraries: /home/users/agebhard/R-test/so1.so: undefined symbol: func2_ Is there any chance to get this working (may be by finding some magic linker option, or using extra dyn.load() arguments in an apropriate way)? Is there another way to share a common subset of C/Fortran functions in different R libraries? (at C/Fortran source code level. Of course I can access functions from other librariues with .C()/.Fortran calls from R source code level, that's not the problem) Is the only solution to write a shared (or static) library, which will be linked to both R libraries? Thanks in advance for any hints. Albrecht ...................................................................... | Albrecht Gebhardt Tel.: (++43 463) 2700/832 | | Institut fuer Mathematik Fax : (++43 463) 2700/834 | | Universitaet Klagenfurt mailto:albrecht.gebhardt@uni-klu.ac.at | | Villacher Str. 161 http://www-stat.uni-klu.ac.at/~agebhard | | A-9020 Klagenfurt, Austria | `--------------------------------------------------------------------' -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html Send "info", "help", or "[un]subscribe" (in the "body", not the subject !) To: r-devel-request@stat.math.ethz.ch _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
On Wed, 6 Sep 2000, Albrecht Gebhardt wrote:> > Hi, > > I am searching for a way to solve the following problem: > > I want to use an external function, defined in a dyn.load()ed shared > object, in another dyn.load()ed shared object. > > Currently I have to take the sources (Fortran) from one libraries src/ > directory and copy them into the src/ dir of the other library, resulting > in two copies of this function. This is bad for maintanance and maybe > also for runtime behaviour because of side effects I'm not aware off (one > symbol could be loaded twice). It would be nice if I could call the > function directly from C/Fortran, after dyn.load()ing both libraries. > But unfortunately this seems to depend very crucially on the > specific OS. > > An example (C/Fortran mix, but I tried also C/C and Fortran/Fortran): > **** so1.c ******************* > #include <R.h> > void func1(double* a, int* n){ > printf("in func1\n"); > F77_SYMBOL(func2)(a,n); > printf("back in func1\n"); > } > ****************************** > gcc -g -fpic -c so1.c -I/usr/local/lib/R/include > ld -shared so1.o -o so1.so > > **** so2.f ******************* > subroutine func2(a,n) > real*8 a(*) > integer n > > integer i > call intpr("in func2",8,0,0) > do 10 i=1,n > a(i)=2.0d0 * a(i) > 10 continue > return > end > ****************************** > g77 -g -fpic -c so2.f > ld -shared so2.o -o so2.so > > on the Alpha (R 1.1.0 on alpha-dec-osf4.0) it works without problems: > > dyn.load("so2.so") > > dyn.load("so1.so") > > .C("func1",as.double(c(1,2,3)),as.integer(3)) > in func1 > in func2 > [1] > back in func1 > [[1]] > [1] 2 4 6 > > [[2]] > [1] 3 > > on Linux (R 1.1.1, SuSE 6.4) it works not: > > dyn.load("so2.so") > > dyn.load("so1.so") > Error in dyn.load(x, as.logical(local), as.logical(now)) : > unable to load shared library > "/home/users/agebhard/R-test/so1.so": > /home/users/agebhard/R-test/so1.so: undefined symbol: func2_ > > or also not working: > > dyn.load("so2.so") > > dyn.load("so1.so",now=F) > > .C("func1",as.double(c(1,2,3)),as.integer(3)) > in func1 > /usr/lib/R/bin/R.bin: error in loading shared > libraries: /home/users/agebhard/R-test/so1.so: undefined symbol: func2_ > > > > Is there any chance to get this working (may be by finding some magic > linker option, or using extra dyn.load() arguments in an apropriate way)? > > Is there another way to share a common subset of C/Fortran functions in > different R libraries? (at C/Fortran source code level. Of course I can > access functions from other librariues with .C()/.Fortran calls from R > source code level, that's not the problem) > > Is the only solution to write a shared (or static) library, which will be > linked to both R libraries? > >... well, I found (at least) one solution:> dyn.load("so1.so",now=F) > dyn.load("so2.so",local=F) > .C("func1",as.double(c(1,2,3)),as.integer(3))in func1 in func2 [1] back in func1 [[1]] [1] 2 4 6 [[2]] [1] 3>but the question remains: What is the best way to share common C/Fortran sources across R libraries? How should I implement the above solution in the libraries? What are the side effects? Is it really portable (win32?)? Albrecht ...................................................................... | Albrecht Gebhardt Tel.: (++43 463) 2700/832 | | Institut fuer Mathematik Fax : (++43 463) 2700/834 | | Universitaet Klagenfurt mailto:albrecht.gebhardt@uni-klu.ac.at | | Villacher Str. 161 http://www-stat.uni-klu.ac.at/~agebhard | | A-9020 Klagenfurt, Austria | `--------------------------------------------------------------------' -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html Send "info", "help", or "[un]subscribe" (in the "body", not the subject !) To: r-devel-request@stat.math.ethz.ch _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
On Wed, 6 Sep 2000, Albrecht Gebhardt wrote:> > ... well, I found (at least) one solution: > > > dyn.load("so1.so",now=F) > > dyn.load("so2.so",local=F) > > .C("func1",as.double(c(1,2,3)),as.integer(3)) > in func1 > in func2 > [1] > back in func1 > [[1]] > [1] 2 4 6 > > [[2]] > [1] 3 > > > > > but the question remains: > > What is the best way to share common C/Fortran sources across R libraries? > How should I implement the above solution in the libraries? What are the > side effects? Is it really portable (win32?)?It is not portable. You will not even be able to make both shared objects on some systems, including AIX and Windows, as they need to know where the symbols are going to be satisfied. And those flags (especially local=F) do not always work (which is why this worked on OSF4, I think). The best way that I know of is to put shared code in a shared library, and link so?.so against that. The only potential problem is putting the common library somewhere it will be found at run time if it is a shared library/DLL, so I would use a static library unless the code was large (like all of LAPACK). (This is particularly a problem on Windows, where the rules for finding DLLs differ by Windows version.) -- Brian D. Ripley, ripley@stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272860 (secr) Oxford OX1 3TG, UK Fax: +44 1865 272595 -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html Send "info", "help", or "[un]subscribe" (in the "body", not the subject !) To: r-devel-request@stat.math.ethz.ch _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._