Thanks for the help. I just thought I should report back with the solution to 
my issues for posterity.

It seems that the header only interface is the way to go for my purposes 
because I only have a few data structures which need to be shared across 
compilation units, and almost all of the code is in the headers. To expose the 
data structures, I created a few accessor functions like:

void registerDirectedStatistic(Rcpp::XPtr< ernm::Stat<ernm::Directed> > ps){
        ernm::StatController<ernm::Directed>::addStat(
                        std::tr1::shared_ptr< ernm::Stat<ernm::Directed> 
>(ps->cloneUnsafe()));
}

Something that had tripped me up is that I had previously had my objects 
returning safe pointers (shared_ptr) when they were cloned. For reasons beyond 
my current understanding, these pointers became unsafe when passed from code 
compiled in inline, to the package object. This caused the segfault that I 
reported before. Next, I followed JJ's advise and registered the function with 
R, and created a macro to simplify calling

R_RegisterCCallable("ernm",
        "registerDirectedStatistic",(DL_FUNC) &registerDirectedStatistic);

#define REGISTER_DIRECTED_STATISTIC(x) ((void(*)(Rcpp::XPtr< 
ernm::Stat<ernm::Directed> >))R_GetCCallable("ernm", 
"registerDirectedStatistic"))(x)

I also exposed the function in my module.

        function("registerDirectedStatistic",&registerDirectedStatistic);

So now there are two ways for the user to add Stats to the data structure. They 
can pass a pointer up to R, and then down to ernm.

getPointer <- cxxfunction(signature(), 
        "
        return Rcpp::XPtr< Stat<Directed> >(new Edges2<Directed>());
        ", 
        plugin="ernm",includes=src)
pointerToNewStat <- getPointer()
registerDirectedStatistic(pointerToNewStat)

or, just register it directly in compiled code

registerEdges2Statistic <- cxxfunction(signature(), 
        "
        Rcpp::XPtr< Stat<Directed> > ps(new Edges2<Directed>());
        REGISTER_DIRECTED_STATISTIC(ps);
        ", 
        plugin="ernm",includes=src)
registerEdges2Statistic()

Best,
Ian


On Nov 16, 2012, at 8:50 AM, JJ Allaire <[email protected]> wrote:

> Anyhow, I think I am probably missing some linking info from my inlinePlugIn 
> statement.
> 
> This is the key -- plugins that do linking are much more complicated than 
> ones that rely on headers only. You can look at the Rcpp and RcppGSL packages 
> as examples -- in short there needs to be a function inside the package that 
> can cough up the correct library locations. If you get this far then your 
> stuff will work with inline and Rcpp::cppFunction, however people developing 
> packages that want to link against your stuff will need custom Makevars 
> entries (which you can configure the inline plugin to produce, but by now 
> things have gotten pretty complicated for your users).
> 
> If you can manage to do header-only "linking" that will be much, much 
> simpler. At the lowest level the key to this is R_GetCCallable. In Rcpp land 
> there is a GetCppCallable equivalent that works with modules. You can see the 
> use of this in the header file which is generated by Rcpp::interfaces(r, cpp).
> 
> If you want to expose the data structure using this mechanism then you could 
> write a function like this:
> 
> // [[Rcpp::export]]
> Rcpp::List getModelStatistics() {
>    return StatController::getModelStatistics();
> }
> 
> And then compileAttributes will automatically generate the shim that calls 
> GetCppCallable.
> 
> 

_______________________________________________
Rcpp-devel mailing list
[email protected]
https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel

Reply via email to