在PHP扩展中封装C++类
Wrapping C++ Classes in a PHP Extension
我正在学习在php扩展中包装c++类的教程。我使用的是wamp服务器和php5.4.16。
PHP_METHOD(Car, __construct)
出现问题。
打电话给后
car_object *obj = ( car_object *) zend_object_store_get_object ( object TSRMLS_CC );
则CCD_ 2不是有效地址。当注释行obj ->car = car
时,wamp没有关闭。所以我认为obj ->car
不是有效或合法的地址。
下面是我的代码:
车辆.cc:
#include "php.h"
#include "car.h"
#define PHP_VEHICLES_EXTNAME "vehicles"
#define PHP_VEHICLES_EXTVER "0.1"
zend_object_handlers car_object_handlers;
struct car_object {
zend_object std;
Car *car;
};
zend_class_entry *car_ce;
void car_free_storage(void *object TSRMLS_DC)
{
car_object *obj = (car_object *)object;
delete obj->car;
zend_hash_destroy(obj->std.properties);
FREE_HASHTABLE(obj->std.properties);
delete obj->car;
efree(obj);
}
zend_object_value car_create_handler(zend_class_entry *type TSRMLS_DC)
{
zend_object_value retval;
car_object *obj = (car_object *)emalloc(sizeof(car_object));
memset(obj, 0, sizeof(car_object));
obj->std.ce = type;
ALLOC_HASHTABLE(obj->std.properties);
zend_hash_init(obj->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
#if PHP_VERSION_ID < 50399
zval *tmp;
zend_hash_copy(obj->std.properties, &type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *)&tmp, sizeof(zval *));
#else
object_properties_init(&(obj->std), type);
#endif
retval.handle = zend_objects_store_put(obj, NULL, car_free_storage, NULL TSRMLS_CC);
retval.handlers = &car_object_handlers;
return retval;
}
PHP_METHOD(Car, __construct)
{
long maxGear;
Car *car = NULL;
zval *object = getThis();
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &maxGear) == FAILURE) {
RETURN_NULL();
}
car = new Car(maxGear);
car_object *obj = ( car_object *) zend_object_store_get_object(object TSRMLS_CC );
//obj->car = car;
}
...
...
zend_function_entry car_methods[] = {
PHP_ME(Car, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
PHP_ME(Car, shift, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Car, accelerate, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Car, brake, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Car, getCurrentSpeed, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Car, getCurrentGear, NULL, ZEND_ACC_PUBLIC)
{NULL, NULL, NULL}
};
PHP_MINIT_FUNCTION(vehicles)
{
zend_class_entry ce;
INIT_CLASS_ENTRY(ce, "Car", car_methods);
car_ce = zend_register_internal_class(&ce TSRMLS_CC);
car_ce->create_object = car_create_handler;
memcpy(&car_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
car_object_handlers.clone_obj = NULL;
return SUCCESS;
}
zend_module_entry vehicles_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
PHP_VEHICLES_EXTNAME,
NULL, /* Functions */
PHP_MINIT(vehicles),
NULL, /* MSHUTDOWN */
NULL, /* RINIT */
NULL, /* RSHUTDOWN */
NULL, /* MINFO */
#if ZEND_MODULE_API_NO >= 20010901
PHP_VEHICLES_EXTVER,
#endif
STANDARD_MODULE_PROPERTIES
};
ZEND_GET_MODULE ( vehicles );
car.h car.cc与教程中的内容相同。
我想我错过了什么。也许是对";CCD_ 5";函数car_create_handler
中的错误。。
谢谢你的帮助。
在您的函数car_free_storage中,您似乎调用了delete obj->car两次。这可能不是个好主意。
此外,当我最近查看另一个php模块时,我发现obj->std.properties并不总是设置为有效地址。因此,在将其传递给zend_hash_destroy之前,可能值得检查它是否为0。我的代码是:
if(obj->std.properties){
zend_hash_destroy(obj->std.properties);
FREE_HASHTABLE(obj->std.properties);
}
相关文章:
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 将可变参数函数的参数封装在类实例中
- 如何封装一个函数,以便它只能由同一类中的一个其他函数调用?
- 封装C++模板
- 将 RTOS 队列对象封装在仅具有静态分配的 IQueue 自定义接口中
- 从封装在对象中的函数 C++ 返回时为空的列表
- 当要访问的对象被多次封装时,如何正确使用setter
- 在为嵌套类定义行外友元时,我真的必须打破封装吗?
- 如何在类中封装C/C++套接字发送和接收函数?
- 如何使用吸气剂方法实现C++封装
- 封装 std::map 以允许迭代,但没有直接密钥访问?
- 类C++友元函数无法访问封装的类
- 当从成员类调用封装的std::begin时,程序崩溃
- 从私有成员类中断封装派生的模板类
- C++实用程序,用于将长开关语句转换为封装开关案例阶梯的简洁函数调用
- 如何修复列表视图中的错误?,封装控件时无法选择任何项
- 我们可以使用命名空间实现封装吗?
- 封装 std::vector 以允许迭代,但不允许其他内容
- lambda[=] 上的复制值被另一个封装的 lambda[&] 阻止
- 如何使用提升范围将自定义迭代器封装在函数中