Hello,
This is somewhat of a known issue we have with windows for some time.
Thanks for looking into it.
If I apply your suggestion to the generator file and it does not break
existing code (i.e. as defined by our unit tests), would you be willing
to test it on your settings ?
Romain
Le 2013-06-13 10:17, QRD a écrit :
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
_______________________________________________
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