glReadPixels調査

phpopengl の glReadPixels が動かないので調査。

php_array_to_long_array した配列を glReadPixels に渡して、
その中に描画バッファを転送させようとして落ちてる。

gdb

Program received signal SIGSEGV, Segmentation fault.
0x00c3473c in memcpy () from /lib/i686/nosegneg/libc.so.6
(gdb) bt
#0  0x00c3473c in memcpy () from /lib/i686/nosegneg/libc.so.6
#1  0x03b51cb0 in __glEmptyImage () from /usr/lib/libGL.so.1

コピー領域が確保できてない系の落ち方です。

php_convert.h

#define php_array_to_long_array(z) (long *)php_array_to_c_array(z,TO_C_LONG,sizeof(long),NULL)

php_convert.c

(関係ない所たくさん削ってみた)

void *php_array_to_c_array(zval *param,int type,int size,int *array_size)
{
    HashTable *param_ht = param->value.ht;
    tmp_size = zend_hash_num_elements(param_ht);
    zend_hash_internal_pointer_reset(param_ht);
    params = (void *)emalloc(size * tmp_size);
    while(zend_hash_get_current_data(param_ht,(void **)&cur) == SUCCESS) {
         convert_to_long(*cur);
         ((long*)params)[i] = Z_LVAL_P(*cur);
         zend_hash_move_forward(param_ht);
         i++;
    }
    return (void *)params;
}

文字通り、PHP の配列を C の配列にマッピングする関数です。

しかも、(上で引用したコードでは省略されてるけど)
入れ子な配列もきちんと、構造体への参照にしてくれる優れもの。

書簡

そもそも、呼ぶ前に必要な分(width x height)の array を確保しない時点で落ちるのは、PHPAPI として不味いので、そこから見直すべきですが、
width x height 分の array を渡しても落ちたので、多分そもそも動かない。
LONG(4byte)分のメモリ領域を確保してくれてるはずなので、パッと見は大丈夫そうなのですが。
なんだろう。