<div dir="ltr"><div><br></div><div>By the way, maybe you should look two files in `inst`.</div><div><br></div><div>The `gen_function.R` crawls <a href="http://redis.io/commands">http://redis.io/commands</a> and generates the command according to the official redis manual. You could modify `template.R` to generate the helper functions dynamically based on the exposed Rcpp function.</div>

<div><br></div><div>Hope it helps.</div><div><br></div><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I may do something like that tomorrow evening.<br>
<br>
For now, I did something _much_ simpler still.   We need single C++ source<br>
file.  Some key features:<br>
<br>
-- no more Boost shared_ptr<br>
-- no more Rcpp::XPtr<br>
-- "empty" constructor and destructor, nothing to be done<br>
-- no member variables<br>
-- one worker function which takes string (with a redis command), runs it<br>
   and returns the result string<br>
-- the worker function checks if the redis context pointer is non-NULL; in<br>
   case it is NULL (eg first use) it creates a context<br>
<br>
-----------------------------------------------------------------------------<br>
<br>
#include <Rcpp.h><br>
#include <hiredis/hiredis.h>    // on Ubuntu file /usr/include/hiredis/hiredis.h<br>
<br>
// We use a static pointer which makes the variable persistent across calls<br>
// A more formal C++ idiom would be a singleton class, but this is simpler<br>
static redisContext *prc = NULL;<br>
<br>
<br>
// A simple and lightweight class -- without member variables<br>
// We could add some member variables to cache the last call, status, ...<br>
//<br>
class Redis {<br>
<br>
private:<br>
    void checkAndInit() {<br>
        if (prc == NULL) {<br>
            prc = redisConnect("127.0.0.1", 6379);<br>
            // should test for error here, could even throw() under Rcpp, ...<br>
            Rcpp::Rcout << "Context created\n";<br>
        } else {<br>
            Rcpp::Rcout << "Reusing context\n";<br>
        }<br>
    }<br>
<br>
public:<br>
    Redis()  { /* Rcpp::Rcout << "In ctor\n"; */ }<br>
    ~Redis() { /* Rcpp::Rcout << "In dtor\n"; */ }<br>
<br>
    std::string execCommand(std::string cmd) {<br>
        checkAndInit();         // important: ensure prc is set up, re-use if so<br>
        redisReply *reply = static_cast<redisReply*>(redisCommand(prc, cmd.c_str()));<br>
        std::string res(reply->str);<br>
        freeReplyObject(reply);<br>
        return(res);<br>
    }<br>
<br>
    void disconnect() {<br>
        redisFree(prc);<br>
        prc = NULL;             // just to be on the safe side<br>
    }<br>
<br>
    // could create new functions to (re-)connect with given host and port etc pp<br>
};<br>
<br>
-----------------------------------------------------------------------------<br>
<br>
Couple this with a simple function (which is so simple that I wrote it<br>
"straight" without even Rcpp attributes. One string in, one string out:<br>
<br>
<br>
-----------------------------------------------------------------------------<br>
// for now, single worker function<br>
extern "C" SEXP execRedisCommand(SEXP p) {<br>
    Redis redis;<br>
    std::string txt = Rcpp::as<std::string>(p);<br>
    std::string res = redis.execCommand(txt);<br>
    return Rcpp::wrap(res);<br>
}<br>
-----------------------------------------------------------------------------<br>
<br>
<br>
(We could create a second function to close redis and call disconnect();<br>
and we could 'getter' function for the state variables inside the context.)<br>
<br>
This function is then used by a single R function:<br>
<br>
-----------------------------------------------------------------------------<br>
## minimal R interface to redis using the hiredis library<br>
redis <- function(cmd) {<br>
    ## some sanity checking on cmd would be nice too...<br>
    .Call("execRedisCommand", cmd, package="Rhiredis")<br>
}<br>
-----------------------------------------------------------------------------<br>
<br>
And that is all.  I added a simple tester:<br>
<br>
edd@don:~/git/Rhiredis$ Rscript tests/simpleRedisClient.R<br>
Context created<br>
[1] "PONG"<br>
Reusing context<br>
[1] "PONG"<br>
Reusing context<br>
[1] "PONG"<br>
Reusing context<br>
[1] "OK"<br>
Reusing context<br>
[1] "42"<br>
edd@don:~/git/Rhiredis$<br>
<br>
As you can see from the verbose text from checkAndInit(), we only need to<br>
create the redis instance once.<br>
<br>
I may still turn this into something based on Rcpp modules. Maybe tomorrow.<br>
<br>
The code is for now in a quick fork of your Rhiredis in my github account.<br>
<br>
Hope this helps,  Dirk<br>
<span class="HOEnZb"><font color="#888888"><br>
<br>
--<br>
Dirk Eddelbuettel | <a href="mailto:edd@debian.org">edd@debian.org</a> | <a href="http://dirk.eddelbuettel.com" target="_blank">http://dirk.eddelbuettel.com</a><br>
</font></span></blockquote></div><br></div></div>