我在我的应用程序中嵌入 PHP(用 Delphi 2010 编写),使用 PHP4Delphi 组件与 php5ts.dll 进行交互。我猜我的程序充当 PHP(sapi 模块?)的扩展,因为它注册了一些可在 PHP 脚本中使用的函数和常量……无论如何,在使用简单数据类型时效果很好,但是当我尝试使用多维数组时作为返回值我得到错误
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?
我尝试将 1 添加到每个数组的 refcount(虽然 MAKE_STD_ZVAL 已经将 refcount 初始化为 1)并且可以治愈 AV 但有时应用程序在执行脚本时会消失 - 我怀疑它会导致引擎的内存管理器中的无限递归,导致 php DLL 和随身携带应用程序...当将 refcount 设置为 0(零;假设在 PHP 脚本中分配返回值时,它的 refcount 将为 1,然后当 PHP 变量超出范围时,它将被销毁)似乎工作(即没有崩溃,没有 AV)但脚本不会生成任何输出,只是空的 html 文件......
我还将数据作为数组发送到我的函数中,然后使用zend_hash_find
等zend_hash_get_current_data
来读取数据。这会弄乱变量的引用计数吗?zend_hash_find
即,当我完成它时,我是否必须减少返回的变量的 refcout ?
迭代数组时重用相同的变量是否安全,即
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?
TIA
艾因