xsubpp c ++异常

时间:2011-06-23 10:49:26

标签: c++ perl

xsubpp可以为从.xs文件转换的c / c ++文件生成异常处理代码。它为我生成以下代码

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

但是在编译生成的代码时,由于TRY,BEGHANDLERS,CATCHALL,ENDHANDLERS未在perl头文件中的任何位置定义,因此编译错误。我修改了我的代码来定义上面提到的令牌。

#define TRY try
#define BEGHANDLERS
#define CATCHALL catch (...) {
#define ENDHANDLERS }

但是我无法为Xname和Xreason提供有意义的定义。以上定义是否正确?我们如何处理上述关键字

3 个答案:

答案 0 :(得分:2)

这属于“当时不做那种”类别。 (对医生的规范回答,当我做X时疼痛)。查看生成的代码:

CATCHALL
    sprintf(errbuf, "%s: %s\tpropagated", Xname, Xreason);
ENDHANDLERS

这不会传播异常。它正在打印一条消息,然后完全忽略了发生错误的事实!

Perl对C ++的支持相当薄弱。这不应该是那么令人惊讶; perl是用C语言编写的,目标是C的外部子程序。

我的建议:处理异常,但不要使用xsubpp为“免费”提供的那些相当笨重的异常内容。而是自己编写try ... catch ...块。使catch块将捕获的C ++异常转换为perl异常。对于致命错误,请调用Perl_croak,针对非致命错误调用Perl_warn

祝你好运。将perl连接到C / C ++并不容易。

一些可能有用的链接:

答案 1 :(得分:0)

我对xsubpp(或者Perl)一无所知,但如果可以假设抛出的异常来自std::exception,那么你可以这样做:

#define CATCHALL catch(const std::exception& ex) {

然后Xreason可以映射到ex.what()Xname比较棘手。你可以使它成为typeid(ex).name(),这可能比什么都好。

这是我能想到的最佳解决方案,除非有一些特定于xsubpp的技巧。

答案 2 :(得分:0)

它看起来像是以语言无关的方式收集信息,然后将其传播到perl。 您显示的代码是生成消息,然后它应该生成代码来传播它:

ENDHANDLERS
if (errbuf[0])
Perl_croak(aTHX_ errbuf);

所以你应该只需挑选出你认为对试图调试它的人有用的任何东西。我认为在消息中包含来自C ++的异常会很有用;并且如前面的答案所述,包括来自e.what()的细节。所以包括这样的东西应该有效:

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