3

Visual C++ ベースのコード (Windows 7) に Perl インタープリター (v 5.16.3) を埋め込んでいます。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 スクリプトも実行されることがわかります。呼び出されたサブルーチンから戻りパラメータを取得することもできます!

なぜNULLになるのか、それが正確に何を意味するのか教えてもらえますか?Ierrgv

編集:

小さな変更を加えることで問題は明らかに解決しますが、使用法に関する詳細な洞察がIerrgvないため、それを解決策と見なす自信はありません。

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

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

追加されたチェックにより、がゼロの場合にのみresult評価されることが保証されます。先ほども言いましたが、これで問題が解決したようです。ERRSVresult

4

1 に答える 1

1

G_KEEPERRERRSV特に( $@) が設定されるのを防ぎます。それを取り除く。

(エラー メッセージを に返すのではなく、表示したままにし$@ます。)

G_KEEPERR が使用される場合、呼び出されたコードのエラーは通常どおり呼び出しを終了し、エラーは呼び出しを超えて伝播しません (G_EVAL の通常のように) が、$@. 代わりに、エラーは警告に変換され、文字列 "\t(in cleanup)" がプレフィックスとして付けられます。これは、 を使用して無効にすることができますno warnings 'misc'。エラー$@がなければクリアされません。

于 2013-06-27T00:45:19.350 に答える