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提供有意义的定义。以上定义是否正确?我们如何处理上述关键字
答案 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";