PHP扩展调用so动态链接库(2)

本文介绍了在PHP扩展中调用so动态链接库时遇到的问题及解决方案,包括如何处理函数参数中的数组,解决扩展模块未成功加载的问题,以及如何从扩展模块返回计算结果到PHP脚本。重点讨论了zval结构,使用宏函数操作数组,并给出了示例代码。
摘要由CSDN通过智能技术生成

问题:so中的函数参数有数组。

比如我的so中的函数叫

int test(double* a)

原来没想太多,直接就调了,果然崩了,报错类似于:
symbol lookup error: ./test: undefined symbol: ……
说白了就是从php调用模块中函数,数组参数到zend引擎中无法解析,这是为什么呢?
这要从PHP的内核说起了:
在PHP中,无论变量是数组型、布尔型,字符串型或者其他任何类型,其信息总会包含在一个zval联合体中。我们一般不直接存取zval,因为比较麻烦,zval中存数组的是个哈希表Hashtable,这个哈希表是一个双向链表来存值。zval的结构是:

    typedef union _zval {
        long lval;
        double dval;
        struct {
        char *val;
        int len;
        } str;
        HashTable *ht;
        zend_object_value obj;
    } zval;

这个东东不是多复杂,有点数据结构基础的人基本都可以看懂。
如果对PHP内核没有兴趣,又嫌直接操作有点麻烦,所以通过一些附加的宏来操作。就记住这几个简单粗暴的宏函数吧~
举个例子,从PHP脚本传入一个都是浮点数的数组,再传给装到本地的so中的C函数,计算后给脚本返回一个整数:

PHP_FUNCTION(hello)
    {
        int argc = ZEND_NUM_ARGS();
        long count1,i,result;
        zval *hello1= NULL;//PHP调用hello传入的数组参数,到这就成zval类型了。
        double data1[count1];//接php数组中值的c数组

        if (zend_parse_parameters(argc TSRMLS_CC, "a", &hello1) == FAILURE)//让扩展把PHP脚本调用hello的参数内容读进来
                        return;
        zval **item1;
        count1 = zend_hash_num_elements(Z_ARRVAL_P(hello1)); 
        zend_hash_internal_pointer_reset(Z_ARRVAL_P(hello1));

       //循环读取zval中的值到c类型的双精度数组data1
        for(i=0;i<count1;i++)
        {
        zend_hash_get_current_data(Z_ARRVAL_P(hello1),(void**)&item1);
        data1[i]=Z_DVAL_PP(item1);
        zend_hash_move_forward(Z_ARRVAL_P(hello1));
         }
        result=test(data1);//调用本地so中的c函数
        RETURN_LONG(re
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值