开发者

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";
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜