Donc, le problème ici est printf
nie R Les mécanismes de collecte construits par l'UE pour les résultats. En particulier, il n'y a pas de flux de fichiers 'stdout' au niveau C et, par conséquent, pas de sortie à collecter dans Rgui ou RStudio. Pour plus de détails, veuillez consulter Section 6.5 Impression de Écriture d'extensions R
Deux solutions possibles :
- Définissez une macro qui définit
printf
à diriger vers Rprintf
et inclure le #define STRICT_R_HEADERS
pour éviter les erreurs .
- Changez les instances de
printf
a Rprintf
dans le code incriminé.
À partir de là, la capture peut être transmise à l'un ou l'autre des éléments suivants capture.output()
qui affecte directement la sortie à une variable, ou bien sink()
qui redirige la sortie vers un fichier dont le contenu doit ensuite être relu à l'aide de la commande readLines()
. Ce dernier permet d'avoir une enveloppe claire sur plusieurs lignes de code pour capturer la sortie, tandis que le précédent se concentre sur la sécurisation de la sortie présente à partir d'une expression entrée.
Option 1
Pour la première itération, il suffit de définir un en-tête qui comprend la définition personnalisée, puis d'inclure la bibliothèque tierce, par exemple
mon_code.h
#ifndef MY_CODE_H
#define MY_CODE_H
#include <R.h>
// this load R_ext/Print.h.
// #include <YOUR_LIBRARY.h>
// Define strict headers
#define STRICT_R_HEADERS
// Map printf to Rprintf
#define printf Rprintf
#endif
crapaud.c
#include <R.h>
#include <Rdefines.h>
#include "my_code.h"
SEXP helloA1() {
printf("Hello World!\n");
return(R_NilValue);
}
exemple de crapaud.R
system("R CMD SHLIB ~/Desktop/toad.c")
dyn.load("~/Desktop/toad.so")
helloA1 <- function() {
result <- .Call("helloA1")
}
# Gregor's suggestion
captured_data = capture.output(helloA1())
# Using sink around multiple function calls to redirect output
# to a single file
sink("sink-examp.txt")
helloA1()
sink()
input_data = readLines("sink-examp.txt")
all.equal(input_data, captured_data)
# [1] TRUE
J'ai implémenté cette approche dans un paquet R que vous pouvez trouver ici :
https://github.com/coatless/printf2Rprintf
Option 2
Cette option redéfinit manuellement le printf
fonctions.
crapaud.c
#include <R.h>
#include <Rdefines.h>
SEXP helloA1() {
Rprintf("Hello World!\n"); // manually changed
return(R_NilValue);
}
exemple de crapaud.R
system("R CMD SHLIB ~/Desktop/toad.c")
dyn.load("~/Desktop/toad.so")
helloA1 <- function() {
result <- .Call("helloA1")
}
# Gregor's suggestion
captured_data = capture.output(helloA1())
# Using sink around multiple function calls to redirect output
# to a single file
sink("sink-examp.txt")
helloA1()
sink()
input_data = readLines("sink-examp.txt")
all.equal(input_data, captured_data)
# [1] TRUE