From albrecht.gebhardt@uni-klu.ac.at  Wed Sep  6 08:04:10 2000
From: albrecht.gebhardt@uni-klu.ac.at (Albrecht Gebhardt)
Date: Wed, 6 Sep 2000 09:04:10 +0200 (MET DST)
Subject: [Rd] reusing external functions across libs
Message-ID: <Pine.OSF.4.21.0009060818570.2418-100000@zidsrv.sci.uni-klu.ac.at>


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


[Rd] reusing external functions across libs
Albrecht Gebhardt