php调用C函数时如何使用zend_parse_parameters

一 zend_parse_parameters原型

int zend_parse_parameters ( int num_args TSRMLS_DC, char* type_spec, ... );
第一个参数是传递给函数的参数个数,通常的做法是传给它ZEND_NUM_ARGS()。这是一个表示传递给函数参数总个数的宏。
第二个参数是为了线程安全,总是传递TSRMLS_CC宏。
第三个参数是一个字符串,指定了函数期望的参数类型。
第四个参数紧跟着需要随参数值更新的变量列表。因为PHP采用松散的变量定义和动态的类型判断,这样做就使得把不同类型的参数转化为期望的类型成为可能。
型。我们从完整性考虑也列出了一些没有讨论到的类型。

下表列出了可能指定的类型。

类型指定符

对应的C类型

描述

l

long

符号整数

d

double

浮点数

s

char *, int

二进制字符串,长度

b

zend_bool

逻辑型(1或0)

r

zval *

资源(文件指针,数据库连接等)

a

zval *

联合数组

o

zval *

任何类型的对象

O

zval *

指定类型的对象。需要提供目标对象的类类型

z

zval *

任何操作的zval 


zval是Zend引擎的值容器[1]。无论这个变量是布尔型,字符串型或者其他任何类型,其信息总会包含在一个zval联合体中。本章中我们不直接存取zval,而是通过一些附加的宏来操作。下面的是或多或少在C中的zval, 以便我们能更好地理解接下来的代码。

[cpp]  view plain copy
  1. typedef union _zval {  
  2. long lval;  
  3. double dval;  
  4. struct {  
  5.   char *val;  
  6.   int len;  
  7. } str;  
  8. HashTable *ht;  
  9. zend_object_value obj;  
  10. } zval;  
  11.   
  12. if (zend_parse_parameters(argc TSRMLS_CC, "sl", &str, &str_len, &n) == FAILURE)  
  13.    return;  

注意到自动生成的代码会检测函数的返回值FAILUER(成功即SUCCESS)来判断是否成功。如果没有成功则立即返回,并且由zend_parse_parameters()负责触发警告信息。因为函数打算接收一个字符串l和一个整数n,所以指定 ”sl” 作为其类型指示符。s需要两个参数,所以我们传递参考char * 和 int (str 和 str_len)给zend_parse_parameters()函数。   

二 内存管理


用于从堆中分配内存的PHP API几乎和标准C API一样。在编写扩展的时候,使用下面与C对应(因此不必再解释)的API函数:
emalloc(size_t size);
efree(void *ptr);
ecalloc(size_t nmemb, size_t size);
erealloc(void *ptr, size_t size);
estrdup(const char *s);
estrndup(const char *s, unsigned int length);
建议 使用这些内存分配函数。 这些函数的优点是:任何分配的内存在偶然情况下如果没有被释放,则会在页面请求的最后被释放。因此,真正的内存泄漏不会产生。还有一个重要的原因,你不需要检查这些内存分配函数的返回值是否为null。当内存分配失败,它们会发出E_ERROR错误,从而决不会返回到扩展。

三 PHP函数中返回值

扩展API包含丰富的用于从函数中返回值的宏。这些宏有两种主要风格:第一种是RETVAL_type()形式,它设置了返回值但C代码继续执行。这通常使用在把控制交给脚本引擎前还希望做的一些清理工作的时候使用,然后再使用C的返回声明 ”return” 返回到PHP;后一个宏更加普遍,其形式是 RETURN_type(),他设置了返回类型,同时返回控制到PHP。

 

设置返回值并且结束函数

设置返回值

宏返回类型和参数

RETURN_LONG(l)

RETVAL_LONG(l)

整数

RETURN_BOOL(b)

RETVAL_BOOL(b)

布尔数(1或0)

RETURN_NULL()

RETVAL_NULL()

NULL

RETURN_DOUBLE(d)

RETVAL_DOUBLE(d)

浮点数

RETURN_STRING(s, dup)

RETVAL_STRING(s, dup)

字符串。如果dup为1,引擎会调用estrdup()重复s,使用拷贝。如果dup为0,就使用s

RETURN_STRINGL(s, l, dup)

RETVAL_STRINGL(s, l, dup)

长度为l的字符串值。与上一个宏一样,但因为s的长度被指定,所以速度更快。

ETURN_TRUE

RETVAL_TRUE

返回布尔值true。注意到这个宏没有括号。

RETURN_FALSE

RETVAL_FALSE

返回布尔值false。注意到这个宏没有括号。

RETURN_RESOURCE(r)

RETVAL_RESOURCE(r)

资源句柄。

 

转载自:http://blog.csdn.net/wzhwho/article/details/6952352

`gst_parse_launch` 是 GStreamer 库中的一个函数,它解析一个给定的描述 GStreamer 管道的文本性描述字符串,并返回一个可运行的 `GstPipeline` 对象。`uridecodebin` 是一个 GStreamer 元素,它可以解码大多数基于 URI 的媒体格式。要使用 `gst_parse_launch` 来播放本地视频文件,你可以按照以下步骤进行: 1. 初始化 GStreamer 库。 2. 使用 `gst_parse_launch` 函数创建一个管道,该管道包含 `filesrc`、`uridecodebin` 和 `autovideosink` 元素。其中 `filesrc` 用于打开本地文件,`uridecodebin` 用于解析并解码视频,`autovideosink` 用于在屏幕上显示视频。 3. 在创建的管道上调用 `gst_element_set_state` 函数,将管道状态设置为 `GST_STATE_PLAYING` 以开始播放。 4. 处理消息,如错误或 EOS(End of Stream)事件,这些事件表明视频播放结束或发生错误。 以下是一个简单的示例代码: ```c #include <gst/gst.h> int main(int argc, char *argv[]) { GstElement *pipeline; GstMessage *msg; GstBus *bus; // 初始化 GStreamer gst_init(&argc, &argv); // 创建管道 pipeline = gst_parse_launch("filesrc location='your-video-file.mp4' ! decodebin ! autovideosink", NULL); // 开始播放 gst_element_set_state(pipeline, GST_STATE_PLAYING); // 获取总线并监听消息 bus = gst_element_get_bus(pipeline); do { msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR | GST_MESSAGE_EOS); // 处理消息 if (msg != NULL) { GError *err; gchar *debug_info; switch (GST_MESSAGE_TYPE(msg)) { case GST_MESSAGE_ERROR: gst_message_parse_error(msg, &err, &debug_info); g_printerr("Error received from element %s: %s\n", GST_OBJECT_NAME(msg->src), err->message); g_printerr("Debugging information: %s\n", debug_info ? debug_info : "none"); g_clear_error(&err); g_free(debug_info); goto beach; case GST_MESSAGE_EOS: g_print("End-Of-Stream reached.\n"); break; case GST_MESSAGE_STATE_CHANGED: // 处理状态改变 break; default: // 忽略不处理的消息 break; } gst_message_unref(msg); } } while (msg != NULL); beach: // 清理 gst_element_set_state(pipeline, GST_STATE_NULL); gst_object_unref(bus); gst_element_unref(pipeline); return 0; } ``` 在上述代码中,请替换 `'your-video-file.mp4'` 为你想要播放的本地视频文件路径。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值