annotate R/rdyncall/R/dynbind.R @ 0:0cfcc391201f

initial from svn dyncall-1745
author Daniel Adler
date Thu, 19 Mar 2015 22:26:28 +0100
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
1 # Package: rdyncall
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
2 # File: R/dynbind.R
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
3 # Description: single-entry front-end to dynamic binding of library functions
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
4
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
5 dynbind <- function(libnames, signature, envir=parent.frame(), callmode="default", pat=NULL, replace=NULL, funcptr=FALSE)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
6 {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
7 # load shared library
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
8 libh <- dynfind(libnames)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
9 if ( is.null(libh) )
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
10 {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
11 cat("dynbind error: Unable to find shared library '", libnames[[1]], "'.\n",sep="")
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
12 cat("For details how to install dynport shared libs, type: ?'rdyncall-demos' might help.\n")
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
13 cat("If there is no information about your OS, consult the projects page how to build and install the shared library for your operating-system.\n")
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
14 cat("Make sure the shared library can be found at the default system places or adjust environment variables (e.g. %PATH% or $LD_LIBRARY_PATH).\n")
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
15 stop("unable to find shared library '", libnames[[1]], "'.\n", call.=FALSE)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
16 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
17
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
18 # -- convert library signature to signature table
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
19
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
20 # eat white spaces
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
21 sigtab <- gsub("[ \n\t]*","",signature)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
22 # split functions at ';'
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
23 sigtab <- strsplit(sigtab, ";")[[1]]
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
24 # split name/call signature at '('
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
25 sigtab <- strsplit(sigtab, "\\(")
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
26
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
27 # -- install functions
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
28
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
29 # make function call symbol
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
30 dyncallfunc <- as.symbol( paste(".dyncall.",callmode, sep="") )
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
31 # report info
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
32 syms.failed <- character(0)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
33
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
34 for (i in seq(along=sigtab))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
35 {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
36 symname <- sigtab[[i]][[1]]
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
37 rname <- if (!is.null(pat)) sub(pat, replace, symname) else symname
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
38 signature <- sigtab[[i]][[2]]
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
39 # lookup symbol
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
40 address <- .dynsym( libh, symname )
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
41
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
42 if (!is.null(address))
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
43 {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
44 # make call function f
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
45 f <- function(...) NULL
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
46 if (funcptr)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
47 {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
48 body(f) <- substitute( dyncallfunc( .unpack(address,0,"p"), signature,...), list(dyncallfunc=dyncallfunc,address=address,signature=signature) )
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
49 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
50 else
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
51 {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
52 body(f) <- substitute( dyncallfunc(address, signature,...), list(dyncallfunc=dyncallfunc,address=address,signature=signature) )
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
53 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
54 environment(f) <- envir # NEW
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
55 # install symbol
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
56 assign( rname, f, envir=envir)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
57 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
58 else
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
59 {
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
60 syms.failed <- c(syms.failed,symname)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
61 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
62 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
63 # return dynbind.report
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
64 x <- list(libhandle=libh, unresolved.symbols=syms.failed)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
65 class(x) <- "dynbind.report"
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
66 return(x)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
67 }