注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

linux 学习

 
 
 

日志

 
 

【原】利用php调用C语言2  

2012-05-10 14:42:26|  分类: PHP |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

     前面实现的函数参数只是简单的类型,但是如何传输结构体和数组呢?
     通过看参考资料《Zend_API:深入_PHP_内核》和《PHP_Extension_Writing之中文版》基本实现了这个功能。


一、 C库的代码

定义了结构体:
struct bsEmaplist
{
        long    ID;
        char    name[128];
        long    pID;
};

这个函数是生成  usrID,并传输给 PHP 代码。
long bsGetUserID(char *name, char *pw, char *usrID)
{
        if(name == NULL || pw == NULL || usrID == NULL)
        {
                return -1; 
        }
        sprintf(usrID, "%s-%s-%s", name, pw, "testID");
        return 0;
}

这个函数把一些信息传输给上级 PHP 。
这些信息为 struct bsEmaplist  结构体数组也  long  型的数据。

long  bsGetEmaplist(char *usrID, long pID, struct bsEmaplist * p, long *num)
{
        int i;

        if(usrID == NULL || p == NULL || num == NULL)
        {
                return -1;
        }
        for(i = 0; i < 5; i++)
        {
                p[i].ID = i;
                p[i].pID = i+1;
                sprintf(p[i].name, "emapname_%d", i);
        }
        *num = 5; 
        return 0; 
}

二、  具体扩展函数的代码


PHP_FUNCTION(bsGetUserID)
{
        char *name, *pw, *usrID;
        int  name_len, pw_len, usrID_len;

        if(ZEND_NUM_ARGS() != 3)
                WRONG_PARAM_COUNT;

        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss" , &name, &name_len, &pw, &pw_len, &usrID, &usrID_len)
== FAILURE)
        {
                RETURN_NULL();
        }
        bsGetUserID(name, pw, usrID);
        php_printf("Username: %s\n", name);
        php_printf("Password: %s\n", pw);
        php_printf("usrID: %s\n", usrID);

        RETURN_TRUE;
}

PHP_FUNCTION(bsGetEmaplist)
{
        zval *             tmp;
        zval *             zlist, znum;
        struct bsEmaplist  emaplist[20];
        long               num;
        int                i;
        char         *     usrID;
        long               usrID_len, pID;


        if(ZEND_NUM_ARGS() != 4)
                WRONG_PARAM_COUNT;

        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "slzz" , &usrID, &usrID_len, &pID, &zlist, &znum) == FAILURE
)
        {
                RETURN_NULL();
        }

        bsGetEmaplist(usrID, pID, emaplist, &num);


        MAKE_STD_ZVAL(tmp);
        if(object_init(tmp) != SUCCESS)
        {
                RETURN_NULL();
        }
        for(i = 0; i < num; i++)
        {
                MAKE_STD_ZVAL(tmp);
                if(object_init(tmp) != SUCCESS);
                php_printf("%d %d %s\n", emaplist[i].ID, emaplist[i].pID, emaplist[i].name);
                add_property_long(tmp, "ID", emaplist[i].ID);
                add_property_long(tmp, "pID", emaplist[i].pID);
                add_property_string(tmp, "name", emaplist[i].name, 1);
                add_index_zval(zlist, i, tmp);
        }
        zval_copy_ctor(zlist);

        RETURN_TRUE;
}

上面主要用到的函数:
    ZEND_NUM_ARGS()                      检查参数个数   
    zend_parse_parameters()              解析参数,相当于 sscanf()  函数 ,具体看 上面的参考资料
    object_init()                                    初始化对象      
    MAKE_STD_ZVAL()  
    add_property_long()                      对象的操作函数,添加 long 型的成员
    add_property_string()                    对象的操作函数,添加 字符串 型的成员
    add_index_zval()                            数组操作函数,添加对象到数组中
    zval_copy_ctor()                            拷贝函数,因为上面赋值只是进行索引,到PHP层不能访问这个内存,所以需要拷贝

三、  测试代码 
<?php
        dl("omatetest.so");

/*

        error_reporting(E_ALL);

        $userId = "";
        $getUserId = bsGetUserID("admin","123456", $userId);
        var_dump($getUserId."*********".$userId);
        echo "<br/>";
        echo 'aaaaa';
*/
        $num = 0;
        $arr = new arrayobject();
        $arr = array();

        $emap = bsGetEmaplist($userId, -1, $arr, $num );
        var_dump($emap);
        echo "<br/>";
        //var_dump($arr);
        print_r($arr);
        echo "<br/>";
        var_dump($num);

四、 输出结果

[root@localhost php]# php demo.php
PHP Notice:  Undefined variable: userId in /root/php/demo.php on line 20
111111
222222
0 1 emapname_0
1 2 emapname_1
2 3 emapname_2
3 4 emapname_3
4 5 emapname_4
bool(true)
<br/>Array
(
    [0] => stdClass Object
        (
            [ID] => 0
            [pID] => 1
            [name] => emapname_0
        )

    [1] => stdClass Object
        (
            [ID] => 1
            [pID] => 2
            [name] => emapname_1
        )

    [2] => stdClass Object
        (
            [ID] => 2
            [pID] => 3
            [name] => emapname_2
        )

    [3] => stdClass Object
        (
            [ID] => 3
            [pID] => 4
            [name] => emapname_3
        )

    [4] => stdClass Object
        (
            [ID] => 4
            [pID] => 5
            [name] => emapname_4
        )

)
<br/>int(0)
  评论这张
 
阅读(1678)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017