我有 Perl XS 代碼,它呼叫來自外部 C 庫的函式,該函式回傳char **(字串陣列)。
XS 代碼最終將回傳給 Perl 一個包含所有字串結果的陣列 ref。或undef失敗。
我有兩個問題:
- 在程式退出時,我得到一個核心轉儲,其中包含有關記憶體損壞、雙重釋放等(例如
double free or corruption (fasttop))的訊息。 - 如何從 XS sub 回傳一個 undef 值,表示出現問題(不是空陣列)?
此外,如果有人可以確認我正確處理了從 Perl 到 C 函式的字串是 utf8 編碼的情況(例如輸入檔案名)或從 C 函式回傳的結果(可能包含 utf8 字串)被發送回Perl 好的。
這是我的代碼(仿照https://stackoverflow.com/a/46719397/385390如果我理解正確,示例 #1):
AV *
decode(infilename_SV)
SV *infilename_SV
PREINIT:
char *infilename;
STRLEN infilename_len;
char **results;
size_t results_sz;
char *aresult;
size_t I;
SV **aresultPP;
char *dummy;
STRLEN dummy_len;
CODE:
infilename = SvPVbyte(infilename_SV, infilename_len)
// call C function
results = myfunc(infilename, &results_sz);
if( results == NULL ){
printf("error!");
// HOW TO return undef (and not an empty array?)
}
// create a Perl array to be returned
RETVAL = (AV*)sv_2mortal((SV*)newAV());
for(I=0;I<results_sz;I ){
results_sz = strlen(results[I]);
// create a new Perl string and copy this result
aresult = newSVpv(results[I], 0);
av_push(RETVAL, aresult);
// free results as returned by C call
free(results[I]);
}
// free results as returned by C call
free(results);
// debug print results
for(I=0;I<results_sz;I ){
aresultPP = av_fetch((AV *)RETVAL, I, 0);
dummy = SvPVbyte(*apayloadPP, dummy_len);
printf("result: %s\n", dummy);
}
OUTPUT:
RETVAL
uj5u.com熱心網友回復:
在程式退出時,我得到一個核心轉儲,其中包含有關記憶體損壞、雙重釋放等的訊息(例如雙重釋放或損壞 (fasttop))。
這可能是因為您覆寫results_sz了for導致未定義行為的回圈變數。
如何從 XS sub 回傳一個 undef 值,表示出現問題(不是空陣列)?
您可以回傳&PL_sv_undef信號未定義的值,有關更多資訊,請參閱perlxs。例如像這樣:
SV *
decode(infilename_SV)
SV *infilename_SV
PREINIT:
char *infilename;
STRLEN infilename_len;
char **results;
size_t results_sz;
char *aresult;
size_t I;
CODE:
infilename = SvPVbyte(infilename_SV, infilename_len);
results = myfunc(infilename, &results_sz);
if( results == NULL ){
RETVAL = &PL_sv_undef;
}
else {
AV *av = newAV();
for(I=0; I < results_sz; I ){
aresult = newSVpv(results[I], 0);
av_push(av, aresult);
free(results[I]);
}
free(results);
RETVAL = sv_2mortal(newRV_noinc((SV*)av));
}
OUTPUT:
RETVAL
如果有人可以確認我正確處理了從 Perl 到 C 函式的字串是 utf8 編碼的情況(例如輸入檔案名)
要將 Perl UTF-8 字串作為 UTF-8 編碼字串傳遞給 C 函式,您可以使用SvPVutf8()而不是SvPVbyte(),請參閱perlguts以獲取更多資訊。例子:
infilename = SvPVutf8(infilename_SV, infilename_len);
或者從 C 函式回傳的結果(可能包含 utf8 字串)被發送回 Perl
您可以使用newSVpvn_flags()而不是newSVpvn()將 UTF-8 編碼的 C 字串轉換為 Perl 字串。例如:
aresult = newSVpvn_flags(results[I], strlen(results[I]), SVf_UTF8);
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/443083.html
