annotate R/rdyncall/man/dyncallback.Rd @ 30:baf087cf5971

- fixed two ref counting problems - minor improvements
author Tassilo Philipp
date Fri, 10 Apr 2020 20:35:19 +0200
parents 0cfcc391201f
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 \name{callback}
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
2 \alias{new.callback}
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
3 \alias{callback}
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
4 \alias{dyncallback}
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
5 \title{Dynamic wrapping of R functions as C callbacks}
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
6 \description{
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
7 Function to wrap R functions as C function pointers.
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
8 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
9 \usage{
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
10 new.callback( signature, fun, envir = new.env() )
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
11 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
12 \arguments{
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
13 \item{signature}{character string specifying the \link[=signature]{call signature} of the C function callback type.}
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
14 \item{fun}{R function to be wrapped as a C function pointer.}
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
15 \item{envir}{the environment in which to evaluate the call to \code{fun}. }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
16 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
17 \details{
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
18 Callbacks are user-defined functions that are registered in a foreign library and that are executed at a later time from within that library.
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
19 Examples include user-interface event handlers that are registered in GUI toolkits, and, comparison functions for custom data types to be passed to generic sort algorithm.
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
20
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
21 The function \code{new.callback} wraps an R function \code{fun} as a C function pointer and returns an external pointer. The foreign C function type of the wrapped
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
22 R function is specified by a \link{call signature} given by \code{signature}.
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
23
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
24 When the C function pointer is called, a global callback handler (implemented in C) is executed first, that dynamically creates an R call expression to \code{fun}
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
25 using the arguments, passed from C and converted to R, according to the \emph{argument types signature} within the \link{call signature} specified. See
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
26 \code{\link{.dyncall}} for details on the format.
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
27 Finally, the handler evaluates the R call expression within the environment given by \code{envir}.
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
28 On return, the R return value of \code{fun} is coerced to the C value, according to the return type signature specified in \code{signature}.
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
29 If an error occurs during the evaluation, the callback will be disabled for further invocations. (This behaviour might change in the future.)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
30
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
31 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
32 \value{
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
33 \code{new.callback} returns an external pointer to a synthetically generated C function.
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
34 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
35
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
36 \section{Portability}{
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
37 The implementation is based on the \emph{dyncallback} library (part of the DynCall project).
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
38
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
39 The following processor architectures are supported: X86, X64, ARM (including Thumb) and partial stable support for PowerPC 32-bit; The library
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
40 has been built and tested to work on various OSs: Linux, Mac OS X, Windows 32/64-bit, BSDs, Haiku, Nexenta/Open Solaris, Minix and Plan9,
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
41 as well as embedded platforms such as Linux/ARM (OpenMoko, Beagleboard, Gumstix, Efika MX, Raspberry Pi), Nintendo DS (ARM), Sony Playstation Portable (MIPS 32-bit/eabi) and iOS (ARM - armv6 mode ok, armv7 unstable).
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
42 Special notes for PowerPC 32-Bit: Callbacks for System V (Linux/BSD) are unstable in this release; MacOS X/Darwin works fine.
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
43 In the context of R, dyncallback has currently no support for callbacks on MIPS, SPARC and PowerPC 64-Bit.
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
44 Using dyncallback to implement non-default calling conventions is not supported yet. (e.g. Window Procedures on Win32/X86).
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
45 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
46 \note{
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
47 The call signature \strong{MUST} match the foreign C callback function type, otherwise an activated callback call from C can lead to a \strong{fatal R process crash}.
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
48
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
49 A small amount of memory is allocated with each wrapper.
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
50 A finalizer function that frees the allocated memory is registered at the external pointer.
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
51 If the external callback function pointer is registered in a C library, a reference should also be held in R as long as the callback can be activated from a foreign C run-time context,
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
52 otherwise the garbage collector might call the finalizer and the next invocation of the callback could lead to a \strong{fatal R process crash} as well.
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
53 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
54
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
55 \references{
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
56 Adler, D. (2012) \dQuote{Foreign Library Interface}, \emph{The R Journal}, \bold{4(1)}, 30--40, June 2012.
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
57 \url{http://journal.r-project.org/archive/2012-1/RJournal_2012-1_Adler.pdf}
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
58
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
59 Adler, D., Philipp, T. (2008) \emph{DynCall Project}.
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
60 \url{http://dyncall.org}
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
61 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
62 \seealso{
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
63 See \code{\link{signature}} for details on call signatures,
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
64 \code{\link{reg.finalizer}} for details on finalizers.
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
65 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
66 \examples{
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
67 \donttest{
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
68 # Create a function, wrap it to a callback and call it via .dyncall:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
69 f <- function(x,y) x+y
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
70 cb <- new.callback("ii)i", f)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
71 r <- .dyncall(cb, "ii)i", 20, 3)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
72
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
73 # Sort vectors directly via 'qsort' C library function using an R callback:
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
74 dynbind(c("msvcrt","c","c.so.6"), "qsort(piip)v;")
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
75 cb <- new.callback("pp)i",function(px,py){
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
76 x <- .unpack(px, 0, "d")
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
77 y <- .unpack(py, 0, "d")
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
78 if (x > y) return(1) else if (x == y) return(0) else return(-1)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
79 })
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
80 x <- rnorm(100)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
81 qsort(x,length(x),8,cb)
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
82 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
83 }
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
84 \keyword{programming}
0cfcc391201f initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
85 \keyword{interface}