Hi, I've just had some trouble, on Windows with Rtools-3.0, throwing exceptions from within a standalone function belonging to a module:
- - - - 8< - - - - crash.cpp #include <stdexcept> #include <Rcpp.h> int calculate(int x) { throw std::invalid_argument("x is invalid"); } RCPP_MODULE(Crash) { Rcpp::function("calculate", &calculate); } - - - - 8< - - - - crash.R require(methods) require(Rcpp) dll.info <- dyn.load("crash") mod <- Module("Crash", dll.info, mustStart = TRUE) mod$calculate(42) - - - - 8< - - - - shell prompt R CMD SHLIB crash.cpp && Rscript crash.R This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information. terminate called after throwing an instance of 'std::invalid_argument' what(): x is invalid - - - - 8< - - - - This is strange as there is a BEGIN_RCPP / END_RCPP pair in the relevant function in Module.cpp: extern "C" SEXP InternalFunction_invoke( SEXP args ){ BEGIN_RCPP SEXP p = CDR(args) ; XP_Function fun( CAR(p) ) ; p = CDR(p) ; UNPACK_EXTERNAL_ARGS(cargs,p) return fun->operator()( cargs ) ; END_RCPP } What seems to be going on is: Under MinGW, you can only throw/catch exceptions across a DLL boundary when linking to the 'DLL runtime'. I'm basing this on quite an old post (from Jan 2011): http://mingw-users.1079350.n2.nabble.com/dlls-and-exceptions-using-a-cross-compiler-td5967925.html This is my situation, because I throw the exception from crash.dll, but it's the above code from Module.cpp in Rcpp.dll which tries to catch it. The R scripts use a link invocation which includes '-static-libgcc': R CMD SHLIB # ... g++ -m64 -shared -s -static-libgcc -o crash.dll # [... etc. ...] and also Rtools's 'g++ -v' reports that it was configured with '--disabled-shared': Target: i686-w64-mingw32 Configured with: [...] --disable-shared --enable-static [...] Thread model: win32 gcc version 4.6.3 20111208 (prerelease) (GCC) This problem doesn't show up with throwing exceptions from class member functions, because in that case, all the work gets done in a template, so the try/catch is compiled into my module's DLL. For an only-mildly-ugly workaround, I put a BEGIN_RCPP / END_RCPP pair around the call in the CppFunction1<OUT, U0> template class (c. line 104 in Module_generated_CppFunction.h): SEXP operator()(SEXP* args) { BEGIN_RCPP // <<-- ADD THIS return Rcpp::module_wrap<OUT>( ptr_fun( /* ... */ ) ); END_RCPP // <<-- AND THIS } This is a template, so it gets compiled into my DLL, the exception never leaves my DLL, and all is well. Because of the '_generated_' in the filename, I haven't created a patch. If the above is right, do you think adding BEGIN_RCPP / END_RCPP pairs in all of the CppFunction-derived classes would be acceptable to work round this feature of the current build set-up under MinGW? Thanks, Ben. _______________________________________________ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel