2013-06-25 65 views
2

我在基於Visual C++的代碼(在Windows 7上)中嵌入了Perl解釋器(v 5.16.3)。其目的是從我的C++程序中調用Perl編寫的用戶編寫的子程序。在C++中嵌入Perl時檢查ERRSV時出現故障(Win32)

的C++代碼來調用Perl的整體結構可以被認爲是如下:

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使用,我不cofident考慮它作爲一個解決方案:

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

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

result增加的檢查確保我們僅在result爲零時才評估ERRSV。正如我剛纔所說,顯然這解決了這個問題。

+0

我有一個類似的問題,在v5.14.2失敗,但在v5.12.4和v5.17.6工作。如果有解釋和解決方案,我很感興趣。 – mob

+0

這將有助於對問題 – ikegami

回答

1

G_KEEPERR明確阻止ERRSV[email protected])被設置。擺脫它。

(保持顯示,而不是在[email protected]返回它的錯誤消息。)

當G_KEEPERR時,在被調用代碼中的任何錯誤將終止該呼叫像往常一樣,並且誤差將不會傳播超出調用(像往常一樣G_EVAL),但它不會進入[email protected]。相反,錯誤將轉換爲警告,並以字符串「\ t(在清除)」作爲前綴。這可以使用no warnings 'misc'來禁用。如果沒有錯誤,[email protected]將不會被清除。

+0

的最小可運行演示看起來是正確的......但我覺得在這方面需要改進Perl文檔。這個句子的構造看起來很奇怪:並且錯誤不會傳播到調用之外(與通常的G_EVAL一樣),但它不會進入$ @。 – Jaywalker

+0

改進方法如何?它非常清楚地說明異常處理與標準的區別。 – ikegami

+0

恕我直言,應避免使用「但」與否定聲明 – Jaywalker