[Rcpp-commits] r1042 - in pkg/Rcpp: R src
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Thu Apr 15 10:10:34 CEST 2010
Author: romain
Date: 2010-04-15 10:10:34 +0200 (Thu, 15 Apr 2010)
New Revision: 1042
Modified:
pkg/Rcpp/R/dot_cpp.R
pkg/Rcpp/src/do_dot_cpp.cpp
Log:
taking the registration info into account
Modified: pkg/Rcpp/R/dot_cpp.R
===================================================================
--- pkg/Rcpp/R/dot_cpp.R 2010-04-14 12:41:13 UTC (rev 1041)
+++ pkg/Rcpp/R/dot_cpp.R 2010-04-15 08:10:34 UTC (rev 1042)
@@ -15,11 +15,28 @@
# You should have received a copy of the GNU General Public License
# along with Rcpp. If not, see <http://www.gnu.org/licenses/>.
+
+is.valid.for.dot.call <- function( symbol ){
+ cl <- oldClass( symbol )
+ identical( cl, "NativeSymbolInfo" ) || identical( cl, c("CallRoutine", "NativeSymbolInfo") )
+}
+
.Cpp <- function(name, ..., PACKAGE){
- symbol <- if( missing(PACKAGE) ){
- getNativeSymbolInfo( name )
+ symbol <- if( inherits( name , "NativeSymbolInfo" ) ){
+ name
} else{
- getNativeSymbolInfo( name, PACKAGE )
+ if( missing(PACKAGE) ){
+ getNativeSymbolInfo( name )
+ } else{
+ getNativeSymbolInfo( name, PACKAGE )
+ }
}
- .External( "do_dot_cpp", symbol$address, ..., PACKAGE = "Rcpp" )
+ if( ! is.valid.for.dot.call(symbol ) ){
+ stop( ".Cpp only supports .Call compatible routines" )
+ }
+ .External( "do_dot_cpp",
+ symbol$address, # external pointer tp the C routine
+ symbol$numParameters, # number of parameters it expects (or NULL)
+ ..., # actual parameters
+ PACKAGE = "Rcpp" )
}
Modified: pkg/Rcpp/src/do_dot_cpp.cpp
===================================================================
--- pkg/Rcpp/src/do_dot_cpp.cpp 2010-04-14 12:41:13 UTC (rev 1041)
+++ pkg/Rcpp/src/do_dot_cpp.cpp 2010-04-15 08:10:34 UTC (rev 1042)
@@ -22,18 +22,15 @@
#include <Rcpp.h>
#include <R_ext/Rdynload.h>
+/* borrowed from R */
+
/* because here we know we are using c++ */
typedef SEXP (*VarFun)(...);
-
-/* This looks up entry points in DLLs in a platform specific way. */
#define MAX_ARGS 65
-
-/* Maximum length of entry-point name, including nul terminator */
#define MaxSymbolBytes 1024
-
-/* Work around casting issues: works where it is needed */
typedef union {void *p; DL_FUNC fn;} fn_ptr;
+/* retrieves a function pointer from an external pointer */
static DL_FUNC get_fun_symbol(SEXP s){
fn_ptr tmp;
tmp.p = EXTPTR_PTR(s);
@@ -55,14 +52,18 @@
/* grab the external pointer to the native routine */
SEXP xp = CADR( args ) ;
+ SEXP np = CADDR( args ) ;
DL_FUNC ofun = get_fun_symbol(xp) ;
SEXP res = R_NilValue ;
/*
- the first argument is "do_dot_cpp"
- the second argument is the external pointer to the function */
- SEXP p = CDDR(args) ;
- if( p == R_NilValue ){
+ SEXP p = CDR(CDDR(args)) ;
+ if( p == R_NilValue ){
+ if( ::Rf_isNull( np ) || INTEGER(np)[0] != 0 ){
+ ::Rf_error( "incorrect number of arguments" ) ;
+ }
/* no arguments, simple case */
try{
res = (SEXP) ofun() ;
@@ -79,8 +80,11 @@
p = CDR(p) ;
}
if( p != R_NilValue ){
- Rf_error( "too many arguments in foreign function call" );
+ ::Rf_error( "too many arguments in foreign function call" );
}
+ if( ! ::Rf_isNull(np) && INTEGER(np)[0] != nargs ){
+ ::Rf_error( "incorrect number of arguments in foreign function call, expecting %d arguments, got %d", INTEGER(np)[0], nargs );
+ }
/* we know there is at least one argument otherwise we would not
be in this branch */
VarFun fun = reinterpret_cast<VarFun>( ofun ) ;
More information about the Rcpp-commits
mailing list