Я встраиваю PHP в свое приложение (написанное в Delphi 2010), используя компонент PHP4Delphi для взаимодействия с php5ts.dll. Я предполагаю, что моя программа действует как расширение для PHP (sapi module?), Поскольку она регистрирует некоторые функции и константы, которые могут использоваться в 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
Строка 1497 в php4delphi.pas - это вызов tsrm_shutdown();
Мне кажется, что сборщик мусора разбился в конце script, поэтому я подозреваю, что я не отправляю данные правильно на двигатель...
таким образом, мой вопрос заключается в том, как предполагается отправить многомерные массивы на 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, но иногда приложение просто исчезает при выполнении script - я подозреваю, что он вызывает бесконечную рекурсию в менеджере memmory Engine, сбой php DLL и приложение с ним...
При установке refcount на 0 (ноль; если предположить, что при возврате значения в PHP script он будет равен 1, а затем, когда переменная PHP выходит из области действия, она будет уничтожена) все, похоже, работают (то есть без сбоев, нет AV), но script не будет генерировать какой-либо вывод, просто пустой html файл...
Я также отправляю данные в виде массивов в свою функцию, затем использую zend_hash_find
, zend_hash_get_current_data
и т.д. для чтения данных. Может ли это испортить пересчет переменных? Т.е. я должен уменьшить refcout переменной, возвращаемой 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?
ТИА
Ain