xsubpp c++ exceptions
xsubpp can generate exception handling code for c/c++ files converted from .xs files. It generates the following piece of code for me
TRY {
char * CLASS = (char *)SvPV_nolen(ST(0));
Example * RETVAL;
RETVAL = new Example();
ST(0) = sv_newmortal();
sv_setref_pv( ST(0), CLASS, (void*)RETVAL );
}
BEGHANDLERS
CATCHALL
sprintf(errbuf, "%s: %s\tpropagated", Xname, Xreason);
ENDHANDLERS
But when compiling the generated code, I'm getting compilation errors as TRY, BEGHANDLERS, CATCHALL, ENDHANDLERS were not defined anywhere in perl header files. I've modified my code to define the above mentioned tokens like this.
#define TRY try
#define BEGHANDLERS
#define CATCHALL catch (...) {
#define ENDHANDLERS }
开发者_开发问答
But I'm not able to give meaningful definitions to Xname and Xreason. Are the above definitions correct ? How do we handle the above mentioned keywords
This falls into the "well don't do that then" category. (The canonical answer to "Doctor, it hurts when I do X"). Look at the generated code:
CATCHALL
sprintf(errbuf, "%s: %s\tpropagated", Xname, Xreason);
ENDHANDLERS
This isn't propagating the exception. It is printing a message and then utterly ignoring the fact that an error occurred!
Perl's support for C++ is rather weak. That shouldn't be that surprising; perl was written in C and targets C for its external subroutines.
My suggestion: Do handle exceptions, but do not use that rather klunky exception stuff provided for 'free' from xsubpp
. Instead write the try ... catch ...
block yourself. Make the catch
block convert those caught C++ exceptions to perl exceptions. Call Perl_croak
for fatal errors, Perl_warn
for non-fatal errors.
And good luck. Interfacing perl to C/C++ is not easy.
Some potentially helpful links:
- "How can I use a C++ class from Perl?" How can I use a C++ class from Perl?
- "Gluing C++ And Perl Together", http://www.johnkeiser.com/perl-xs-c++.html
- "Interfacing Perl with C++, using XS", http://adventures-in-perl.blogspot.com/2010/08/interfacing-perl-with-c-external-files.html
- "Auto-inserting wrappers to handle C++ exceptions", http://www.mail-archive.com/perl-xs@perl.org/msg02248.html
I know nothing about xsubpp (or Perl, for that matter), but if the thrown exception can be assumed to derive from std::exception
, then you could do something like this:
#define CATCHALL catch(const std::exception& ex) {
Then Xreason
could be mapped to ex.what()
. Xname
is trickier. You could make it something like typeid(ex).name()
, which might be better than nothing.
That's the best solution I can think of, unless there is some xsubpp-specific trick.
It looks like it's gathering the info in a language-agnostic way, then propagating it to perl. The code you show is generating the message, then after that it should've generated code to propagate it:
ENDHANDLERS
if (errbuf[0])
Perl_croak(aTHX_ errbuf);
So you should just need to pick out whatever you think would be useful to someone trying to debug it. I think including in the message that the exception came from C++ would be useful; and as the previous answer said, include the detail from e.what(). So including something like this should work:
#include <stdexcept>
#define TRY try
#define BEGHANDLERS catch(std::exception const &e){
#define CATCHALL const char * Xreason = e.what();
#define ENDHANDLERS }
const char * Xname = "C++ exception";
精彩评论