3

我将 Perl 解释器 (v 5.16.3) 嵌入到基于 Visual C++ 的代码中(在 Windows 7 上)。目的是从我的 C++ 程序调用 Perl 中用户编写的子例程。

调用 Perl 的 C++ 代码的整体结构如下:

perl_alloc()
perl_construct()
perl_parse()

dSP 

int result = call_argv(funcName, G_ARRAY|G_EVAL|G_KEEPERR, params);

if (SvTRUE (ERRSV)) // <-- crashes here
{
  :
}

此代码在运行时在标记行上崩溃。问题源于访问 ERRSV,这将是一个宏。做了一些故障排除,我发现麻烦制造者是以下属性:

vTHX->Ierrgv

即,Ierrgv在我的情况下为 NULL。

如果我注释掉这个错误检查(即,SvTRUE),代码本身就可以正常工作,并且我知道我的 Perl 脚本也会被执行。我什至可以从被调用的子程序中检索返回参数!

有人能告诉我为什么Ierrgv会是 NULL,这到底是什么意思?

编辑:

做一个小改动显然可以解决问题,但没有详细了解Ierrgv使用情况,我不敢将其视为解决方案:

int result = call_argv(funcName, G_ARRAY|G_EVAL|G_KEEPERR, params);

if ( (result==0) && (SvTRUE (ERRSV) ) // <-- doesn't crash here
{
  :
}

添加的检查result确保我们ERRSV仅在result为零时进行评估。正如我之前所说,显然这解决了问题。

4

1 回答 1

1

G_KEEPERR专门防止ERRSV( $@) 被设置。摆脱它。

(保持显示错误消息而不是返回它$@。)

当使用 G_KEEPERR 时,被调用代码中的任何错误都会像往常一样终止调用,并且错误不会传播到调用之外(与 G_EVAL 一样),但不会进入$@. 相反,错误将被转换为警告,前缀为字符串“\t(in cleanup)”。这可以使用禁用no warnings 'misc'。如果没有错误,$@将不会被清除。

于 2013-06-27T00:45:19.350 回答