[Rd] reusing external functions across libs

Albrecht Gebhardt albrecht.gebhardt@uni-klu.ac.at
Wed, 6 Sep 2000 09:54:03 +0200 (MET DST)


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
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._