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) ®isterDirectedStatistic);
#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",®isterDirectedStatistic);
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