PHP4Delphi コンポーネントを使用して php5ts.dll とのインターフェイスを使用して、アプリ (Delphi 2010 で記述) に PHP を埋め込んでいます。PHPスクリプトで使用できるいくつかの関数と定数を登録するため、私のプログラムはPHP(sapiモジュール?)の拡張機能として機能すると思います...とにかく、単純なデータ型を使用する場合はうまく機能しますが、多次元配列を使用しようとすると戻り値としてエラーが発生します
Access violation at address 01CD3C35 in module 'php5ts.dll'. Read of address 0231E608.
スタックリスト
(000A2C35){php5ts.dll} [01CD3C35] destroy_op_array + $35
(004C4D61){myApp.exe } [008C5D61] php4delphi.TPHPEngine.ShutdownEngine (Line 1497, "php4delphi.pas" + 17) + $7
php4delphi.pas の 1497 行が呼び出されます。tsrm_shutdown();
私には、スクリプトの最後でガベージコレクターがクラッシュしているように見えるので、エンジンにデータを正しく送り返していないのではないかと疑っています...したがって、多次元配列をPHPに送り返す方法が私の質問ですか?
私が使っているパターンは
var subArray: pzval;
_array_init(return_value, nil, 0);
for x := 0 to Data.Count-1 do begin
subArray := MAKE_STD_ZVAL;
_array_init(subArray, nil, 0);
// populate subarray with data, including other subarrays
...
// add subarray to the main array
add_index_zval(return_value, x, subArray);
end;
作成したサブアレイをどこかに「登録」する必要がありますか? 増減refcount
または設定する必要がありis_ref
ますか? IOW、サブ配列の return_value と zvals をどのように設定する必要がありますか?
各配列のrefcountに1を追加して実験しました(MAKE_STD_ZVALはすでにrefcountを1に初期化していますが)、これでAVは解決しますが、スクリプトを実行するとアプリが消えることがあります-エンジンのメモリマネージャーで無限再帰が発生し、php DLLがクラッシュし、アプリを持っていく... refcountを0に設定すると(ゼロ; PHPスクリプトで戻り値が割り当てられたときにrefcountが1になり、PHP変数がスコープ外になると破棄されると仮定すると)すべてのようです動作します(つまり、クラッシュもAVもありません)が、スクリプトは出力を生成せず、空のhtmlファイルのみを生成します...
また、データを配列として関数に送信し、zend_hash_find
, zend_hash_get_current_data
etc を使用してデータを読み取ります。これにより、変数の参照カウントが台無しになる可能性はありますか? つまり、使い終わったときに返される変数のrefoutを減らす必要がありますzend_hash_find
か?
また、配列を反復処理するときに同じ変数を再利用しても安全ですか。つまり、
var Val: pppzval;
new(Val);
zend_hash_internal_pointer_reset(aZendArr^.value.ht);
for x := 1 to zend_hash_num_elements(aZendArr^.value.ht) do begin
zend_hash_get_current_data(aZendArr^.value.ht, Val);
// read data from Val to local variable and do something with it
zend_hash_move_forward_ex(aZendArr^.value.ht, nil);
end;
Dispose(Val);
または、ループの各反復で Val を作成/解放する必要がありますか?
ティア
・アイン