今天花了几乎一天的时间研究php的相关c++扩展,第一次接触的时候很多地方不太熟悉,也碰到了不少坑,这里把整个过程叙述如下,参考的文章主要是http://devzone.zend.com/1435/wrapping-c-classes-in-a-php-extension/:
现在定义了一个Car类,它有一些成员函数,整个扩展包括的文件如下:
1 PHP_ARG_ENABLE(vehicles, 2 [Whether to enable the "vehicles" extension], 3 [ --enable-vehicles Enable "vehicles" extension support]) 4 5 if test $PHP_VEHICLES != "no"; then 6 PHP_REQUIRE_CXX() 7 PHP_SUBST(VEHICLES_SHARED_LIBADD) 8 PHP_ADD_LIBRARY(stdc++, 1, VEHICLES_SHARED_LIBADD) 9 PHP_NEW_EXTENSION(vehicles, vehicles.cc car.cc, $ext_shared) 10 fi
#ifndef VEHICLES_CAR_H
2 #define VEHICLES_CAR_H
3
4 // A very simple car class
5 class Car {
6 public:
7 Car(int maxGear);
8 void shift(int gear);
9 void accelerate();
10 void brake();
11 int getCurrentSpeed();
12 int getCurrentGear();
13 private:
14 int maxGear;
15 int currentGear;
16 int speed;
17 };
18
19 #endif /* VEHICLES_CAR_H */ 2 #include "car.h"
3 Car::Car(int maxGear) {
4 this->maxGear = maxGear;
5 this->currentGear = 1;
6 this->speed = 0;
7 }
9 void Car::shift(int gear) {
10 if (gear < 1 || gear > maxGear) {
11 return;
12 }
13 currentGear = gear;
14 }
16 void Car::accelerate() {
17 speed += (5 * this->getCurrentGear());
18 }
20 void Car::brake() {
21 speed -= (5 * this->getCurrentGear());
22 }
24 int Car::getCurrentSpeed() {
25 return speed;
26 }1 #ifndef PHP_VEHICLES_H
2 #define PHP_VEHICLES_H
4 #define PHP_VEHICLES_EXTNAME "vehicles"
5 #define PHP_VEHICLES_EXTVER "0.1"
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
10
11 extern "C" {
12 #include "php.h"
13 }
14
15 extern zend_module_entry vehicles_module_entry;
16 #define phpext_vehicles_ptr &vehicles_module_entry;
17
18 #endif /* PHP_VEHICLES_H */1 #include "php_vehicles.h"
2 PHP_MINIT_FUNCTION(vehicles)
3 {
4 return SUCCESS;
5 }
6 zend_module_entry vehicles_module_entry = {
7 #if ZEND_MODULE_API_NO >= 20010901
8 STANDARD_MODULE_HEADER,
9 #endif
10 PHP_VEHICLES_EXTNAME,
11 NULL, /* Functions */
12 PHP_MINIT(vehicles),
13 NULL, /* MSHUTDOWN */
14 NULL, /* RINIT */
15 NULL, /* RSHUTDOWN */
16 NULL, /* MINFO */
17 #if ZEND_MODULE_API_NO >= 20010901
18 PHP_VEHICLES_EXTVER,
19 #endif
20 STANDARD_MODULE_PROPERTIES
21 };
22 #ifdef COMPILE_DL_VEHICLES
23 extern "C" {
24 ZEND_GET_MODULE(vehicles)
25}
26 #endif1 #include "php_vehicles.h"
2 zend_class_entry *car_ce;
3 PHP_METHOD(Car, __construct){}
5 PHP_METHOD(Car, shift) {}
7 PHP_METHOD(Car, accelerate) {}
9 PHP_METHOD(Car, brake) {}
11 PHP_METHOD(Car, getCurrentSpeed){}
13 PHP_METHOD(Car, getCurrentGear){}
15 zend_function_entry car_methods[] = {
16 PHP_ME(Car, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
17 PHP_ME(Car, shift, NULL, ZEND_ACC_PUBLIC)
18 PHP_ME(Car, accelerate, NULL, ZEND_ACC_PUBLIC)
19 PHP_ME(Car, brake, NULL, ZEND_ACC_PUBLIC)
20 PHP_ME(Car, getCurrentSpeed, NULL, ZEND_ACC_PUBLIC)
21 PHP_ME(Car, getCurrentGear, NULL, ZEND_ACC_PUBLIC)
22 {NULL, NULL, NULL}
23 };
24 PHP_MINIT_FUNCTION(vehicles)
25 {
26 zend_class_entry ce;
27 INIT_CLASS_ENTRY(ce, "Car", car_methods);
28 car_ce = zend_register_internal_class(&ce TSRMLS_CC);
29 return SUCCESS;
30 }
31 zend_module_entry vehicles_module_entry = {
32 #if ZEND_MODULE_API_NO >= 20010901
33 STANDARD_MODULE_HEADER,
34 #endif
35 PHP_VEHICLES_EXTNAME,
36 NULL, /* Functions */
37 PHP_MINIT(vehicles), /* MINIT */
38 NULL, /* MSHUTDOWN */
39 NULL, /* RINIT */
40 NULL, /* RSHUTDOWN */
41 NULL, /* MINFO */
42 #if ZEND_MODULE_API_NO >= 20010901
43 PHP_VEHICLES_EXTVER,
44 #endif
45 STANDARD_MODULE_PROPERTIES
46 };
47 #ifdef COMPILE_DL_VEHICLES
48 extern "C" {
49 ZEND_GET_MODULE(vehicles)
50 }
51 #endif1 #include "car.h"
2 zend_object_handlers car_object_handlers;
3 struct car_object {
4 zend_object std;
5 Car *car;
6 };1 void car_free_storage(void *object TSRMLS_DC)
2 {
3 car_object *obj = (car_object *)object;
4 delete obj->car;
5 zend_hash_destroy(obj->std.properties);
6 FREE_HASHTABLE(obj->std.properties);
7 efree(obj);
8 }
9 zend_object_value car_create_handler(zend_class_entry *type TSRMLS_DC)
10 {
11 zval *tmp;
12 zend_object_value retval;
13 car_object *obj = (car_object *)emalloc(sizeof(car_object));
14 memset(obj, 0, sizeof(car_object));
15 obj->std.ce = type;
16 ALLOC_HASHTABLE(obj->std.properties);
17 zend_hash_init(obj->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
18 zend_hash_copy(obj->std.properties, &type->default_properties,
19 (copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *));
20 retval.handle = zend_objects_store_put(obj, NULL,
21 car_free_storage, NULL TSRMLS_CC);
22 retval.handlers = &car_object_handlers;
23 return retval;
24 }25 PHP_MINIT_FUNCTION(vehicles)
26 {
27 zend_class_entry ce;
28 INIT_CLASS_ENTRY(ce, "Car", car_methods);
29 car_ce = zend_register_internal_class(&ce TSRMLS_CC);
30 car_ce->create_object = car_create_handler;
31 memcpy(&car_object_handlers,
32 zend_get_std_object_handlers(), sizeof(zend_object_handlers));
33 car_object_handlers.clone_obj = NULL;
34 return SUCCESS;
35}
1 PHP_METHOD(Car, __construct)
2 {
3 long maxGear;
4 Car *car = NULL;
5 zval *object = getThis();
6 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &maxGear) == FAILURE) {
7 RETURN_NULL();
8 }
9 car = new Car(maxGear);
10 car_object *obj = (car_object *)zend_object_store_get_object(object TSRMLS_CC);
11 obj->car = car;
12 }PHP_METHOD(accelerate)
{
Car *car;
car_object *obj = (car_object *)zend_object_store_get_object(
getThis() TSRMLS_CC);
car = obj->car;
if (car != NULL) {
car->accelerate();
}
}
PHP_METHOD(getCurrentSpeed)
{
Car *car;
car_object *obj = (car_object *)zend_object_store_get_object(
getThis() TSRMLS_CC);
car = obj->car;
if (car != NULL) {
RETURN_LONG(car->getCurrentSpeed());
}
RETURN_NULL();
}<pre class="code">/ create a 5 gear car $car = new Car(5); print $car->getCurrentSpeed(); // prints '0' $car->accelerate(); print $car->getCurrentSpeed(); // prints '5' If you can run this script, congratulations, you’ve just created a PHP extension that wraps a C++ class.
c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号