void R_RegisterCCallable(const char *package, const char *name, DL_FUNC fptr)
{
    SEXP penv = get_package_CEntry_table(package);
    SEXP eptr = R_MakeExternalPtrFn(fptr, R_NilValue, R_NilValue);
    PROTECT(eptr);
    defineVar(install(name), eptr, penv);
    UNPROTECT(1);
}
Exemple #2
0
void rlang_register_pointer(const char* ns, const char* ptr_name, DL_FUNC fn) {
  SEXP ptr = PROTECT(R_MakeExternalPtrFn(fn, R_NilValue, R_NilValue));

  SEXP ptr_obj = PROTECT(Rf_allocVector(VECSXP, 1));
  SET_VECTOR_ELT(ptr_obj, 0, ptr);

  Rf_setAttrib(ptr_obj, R_ClassSymbol, Rf_mkString("fn_pointer"));

  Rf_defineVar(Rf_install(ptr_name), ptr_obj, rlang_namespace(ns));
  UNPROTECT(2);
}
/**
  Creates an R object representing the value of the
  function pointer given by `f'. This object has class
  NativeSymbol and can be used to relay symbols from
  one DLL to another.
 */
static SEXP
Rf_MakeNativeSymbolRef(DL_FUNC f)
{
    SEXP ref, klass;

    PROTECT(ref = R_MakeExternalPtrFn(f, install("native symbol"),
				      R_NilValue));
    PROTECT(klass = mkString("NativeSymbol"));
    setAttrib(ref, R_ClassSymbol, klass);
    UNPROTECT(2);
    return(ref);
}
Exemple #4
0
// returns either the R function or the address of the native routine
// on return, use_native tells whether to use the native or the R function
SEXP pomp_fun_handler (SEXP pfun, SEXP gnsi, pompfunmode *mode)
{
  int nprotect = 0;
  SEXP f = R_NilValue;

  *mode = *(INTEGER(GET_SLOT(pfun,install("mode"))));

  switch (*mode) {

  case Rfun:			// R function

    PROTECT(f = GET_SLOT(pfun,install("R.fun"))); nprotect++;

    break;

  case native: case regNative:	// native code

    if (*(INTEGER(gnsi))) {	// get native symbol information?

      SEXP nf, pack;
      PROTECT(nf = GET_SLOT(pfun,install("native.fun"))); nprotect++;
      PROTECT(pack = GET_SLOT(pfun,install("PACKAGE"))); nprotect++;
      if (LENGTH(pack) < 1) {
        PROTECT(pack = mkString("")); nprotect++;
      }

      switch (*mode) {
      case native:
      {
        SEXP nsi;
        PROTECT(nsi = eval(PROTECT(lang3(install("getNativeSymbolInfo"),nf,pack)),R_BaseEnv)); nprotect += 2;
        PROTECT(f = getListElement(nsi,"address")); nprotect++;
      }
        break;

      case regNative:
      {
        // Before version 3.4.0, R_MakeExternalPtrFn is not part of the R API.
        // Therefore, we must use some trickery to avoid the ISO C proscription of
        //     (void *) <-> (function *) conversion.
        const char *fname, *pkg;
        fname = (const char *) CHAR(STRING_ELT(nf,0));
        pkg = (const char *) CHAR(STRING_ELT(pack,0));
#if (R_VERSION < 197632) // before 3.4.0
        // This is cadged from 'R_MakeExternalPtrFn'.
        union {void *p; DL_FUNC fn;} trick;
        trick.fn = R_GetCCallable(pkg,fname);
        PROTECT(f = R_MakeExternalPtr(trick.p,R_NilValue,R_NilValue)); nprotect++;
#else
        DL_FUNC fn;
        fn = R_GetCCallable(pkg,fname);
        PROTECT(f = R_MakeExternalPtrFn(fn,R_NilValue,R_NilValue)); nprotect++;
#endif
      }
        break;

      case Rfun: case undef: default:
        break;			// # nocov
      }

      SET_SLOT(pfun,install("address"),f);

    } else {			// native symbol info is stored

      PROTECT(f = GET_SLOT(pfun,install("address"))); nprotect++;

    }

    *mode = native;

    break;

  case undef: default:
  {
    const char *purp = (const char *) CHAR(STRING_ELT(GET_SLOT(pfun,install("purpose")),0));

    errorcall(R_NilValue,"operation cannot be completed: %s has not been specified",purp);
  }

  }

  UNPROTECT(nprotect);
  return f;
}
Exemple #5
0
SEXP R_externalptr_prototype_object()
{
    return R_MakeExternalPtrFn((DL_FUNC) R_dummy_extern_place, R_NilValue,
			       R_NilValue);
}