前面实现的函数参数只是简单的类型,但是如何传输结构体和数组呢?
通过看参考资料《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: %sn”, name);
php_printf(“Password: %sn”, pw);
php_printf(“usrID: %sn”, 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 %sn”, 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)

Comments are closed.

Post Navigation