免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 8046 | 回复: 11
打印 上一主题 下一主题

[请问]PHP如何扩展C++, 给一个可行的方案. [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-09-03 11:23 |只看该作者 |倒序浏览
30可用积分
在网上找了很多资料,
步骤都是这样的,

1. 进入PHP源码目录下的ext/目录,
运行: ./ext_skel --extname=testcpp

2. 进入testcpp目录, 修改config.m4
PHP_ARG_ENABLE(testcpp, whether to enable testcpp support,
Make sure that the comment is aligned:
[  --enable-testcpp           Enable testcpp support])

..............

  PHP_REQUIRE_CXX()
  PHP_SUBST(SYSFILE_SHARED_LIBADD)
  PHP_ADD_LIBRARY(stdc++, "", SYSFILE_SHARED_LIBADD)
  PHP_NEW_EXTENSION(testcpp, testcpp.cpp, $ext_shared)

3. .cpp文件该用extern "C"的地方我都用了.

4. phpize

5. ./configure

6. make
在这一步的时候编译不过, 错误信息是:
invalid conversion form 'const zend_function_entry*' to '_zend_function_entry*'

7. make install
当然前面一步编译不过, 这里就不用执行了.


或者按 http://bbs.chinaunix.net/viewthread.php?tid=872895 这帖子来做,
编译是通过了, 但调用.so文件里的函数的时候, 提示找不到函数名.

望XDJM们可以帮我解决这个问题. 先在此谢了.

最佳答案

查看完整内容

这是在php5.2.10下的,最简单版本的扩展。仅仅是为了演示,可以用cpp来扩展。没有加入额外的C++代码。

论坛徽章:
1
技术图书徽章
日期:2013-12-05 23:25:45
2 [报告]
发表于 2009-09-03 11:23 |只看该作者
原帖由 insane 于 2009-9-4 09:49 发表
麻烦你帮我看看这样做正确不:

1 进入php5.3.0/ext目录, 执行:
./ext_skel --extname=vehicles

2 修改.cc及.h文件:

php_vehicles.h:

#ifndef PHP_VEHICLES_H
#define PHP_VEHICLES_H

#define P ...


这是在php5.2.10下的,最简单版本的扩展。
仅仅是为了演示,可以用cpp来扩展。没有加入额外的C++代码。

vehicles.zip

5.86 KB, 下载次数: 105

论坛徽章:
0
3 [报告]
发表于 2009-09-03 11:36 |只看该作者
自己调试,先看phpinfo 里你的扩展是否被加载。 然后用function_exist函数检查你的函数是否存在。

玩过没没问题的

论坛徽章:
0
4 [报告]
发表于 2009-09-03 14:05 |只看该作者
现在编译过了, 但在调用.so文件的时候, 出现以下信息:

Warning: dl() [function.dl]: Dynamically loaded extensions aren't enabled in /var/www/testcpp/testcpp.php on line 5
Functions available in the test extension:

Warning: Invalid argument supplied for foreach() in /var/www/testcpp/testcpp.php on line 10

Module testcpp is not compiled into PHP

论坛徽章:
0
5 [报告]
发表于 2009-09-03 15:57 |只看该作者
还是修改,php.ini还点吧, dl函数的报错似乎是php的配置问题,调用dl确保 dll,或者so放在正确的 ext 目录里
查看 enable_dl = On是否是打开的

[ 本帖最后由 shitou254 于 2009-9-3 16:13 编辑 ]

论坛徽章:
0
6 [报告]
发表于 2009-09-03 18:38 |只看该作者
原帖由 shitou254 于 2009-9-3 15:57 发表
还是修改,php.ini还点吧, dl函数的报错似乎是php的配置问题,调用dl确保 dll,或者so放在正确的 ext 目录里
查看 enable_dl = On是否是打开的


忘记说系统环境了,
用的系统是debian. php5.3.0

已经在php.ini里面加入extension=MODULE_NAME.so了。
也已经确定enable_dl=on,

并参考了 http://devzone.zend.com/article/ ... -in-a-PHP-Extension 上面的例子,
还是报
Warning: dl() [function.dl]: Dynamically loaded extensions aren't enabled in /var/www/testcpp/testcpp.php on line 5
Functions available in the test extension:
这个错。

论坛徽章:
1
技术图书徽章
日期:2013-12-05 23:25:45
7 [报告]
发表于 2009-09-03 20:59 |只看该作者
1. 你用c来做一个最简单的,看是否可以么?
用extension=MODULE_NAME.so这种方式调用

2. 再来扩展c++的。如果前一步都不通过,这一步很难进行了。

论坛徽章:
0
8 [报告]
发表于 2009-09-03 22:39 |只看该作者
原帖由 HonestQiao 于 2009-9-3 20:59 发表
1. 你用c来做一个最简单的,看是否可以么?
用extension=MODULE_NAME.so这种方式调用

2. 再来扩展c++的。如果前一步都不通过,这一步很难进行了。


用扩展C是可以的, 但就是用C++不行。

论坛徽章:
0
9 [报告]
发表于 2009-09-04 09:49 |只看该作者

回复 #6 HonestQiao 的帖子

麻烦你帮我看看这样做正确不:

1 进入php5.3.0/ext目录, 执行:
./ext_skel --extname=vehicles

2 修改.cc及.h文件:

php_vehicles.h:

  1. #ifndef PHP_VEHICLES_H
  2. #define PHP_VEHICLES_H

  3. #define PHP_VEHICLES_EXTNAME  "vehicles"
  4. #define PHP_VEHICLES_EXTVER   "0.1"

  5. #ifdef HAVE_CONFIG_H
  6. #include "config.h"
  7. #endif

  8. extern "C" {
  9. #include "php.h"
  10. }

  11. extern zend_module_entry vehicles_module_entry;
  12. #define phpext_vehicles_ptr &vehicles_module_entry;

  13. #endif /* PHP_VEHICLES_H */
复制代码


vehicles.cc:

  1. #include "php_vehicles.h"
  2. #include "car.h"

  3. #include <iostream>

  4. using namespace std;

  5. zend_object_handlers car_object_handlers;
  6. zend_class_entry *car_ce;

  7. struct car_object {
  8.     zend_object std;
  9.     Car *car;
  10. };

  11. void car_free_storage(void *object TSRMLS_DC)
  12. {
  13.     car_object *obj = (car_object *)object;

  14.     delete obj->car;

  15.     zend_hash_destroy(obj->std.properties);
  16.     FREE_HASHTABLE(obj->std.properties);

  17.     efree(obj);
  18. }

  19. zend_object_value car_create_handler(zend_class_entry *type TSRMLS_DC)
  20. {
  21.     zval *tmp;
  22.     zend_object_value retval;

  23.     car_object *obj = (car_object *)emalloc(sizeof(car_object));
  24.     memset(obj, 0, sizeof(car_object));
  25.     obj->std.ce = type;

  26.     ALLOC_HASHTABLE(obj->std.properties);
  27.     zend_hash_init(obj->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
  28.     zend_hash_copy(obj->std.properties, &type->default_properties,
  29.         (copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *));

  30.     retval.handle = zend_objects_store_put(obj, NULL,
  31.         car_free_storage, NULL TSRMLS_CC);
  32.     retval.handlers = &car_object_handlers;

  33.     return retval;
  34. }

  35. PHP_METHOD(Car, __construct)
  36. {
  37.     long maxGear;
  38.     Car *car = NULL;
  39.     zval *object = getThis();

  40.     if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &maxGear) == FAILURE) {
  41.         RETURN_NULL();
  42.     }

  43.     car = new Car(maxGear);
  44.     car_object *obj = (car_object *)zend_object_store_get_object(object TSRMLS_CC);
  45.     obj->car = car;
  46. }

  47. PHP_METHOD(Car, shift)
  48. {

  49. }

  50. PHP_METHOD(Car, accelerate)
  51. {
  52.     Car *car;
  53.     car_object *obj = (car_object *)zend_object_store_get_object(
  54.         getThis() TSRMLS_CC);
  55.     car = obj->car;
  56.     if (car != NULL) {
  57.         car->accelerate();
  58.     }
  59. }

  60. PHP_METHOD(Car, brake)
  61. {

  62. }

  63. PHP_METHOD(Car, getCurrentSpeed)
  64. {
  65.     Car *car;
  66.     car_object *obj = (car_object *)zend_object_store_get_object(
  67.         getThis() TSRMLS_CC);
  68.     car = obj->car;
  69.     if (car != NULL) {
  70.         RETURN_LONG(car->getCurrentSpeed());
  71.     }
  72.     RETURN_NULL();
  73. }

  74. PHP_METHOD(Car, getCurrentGear)
  75. {

  76. }

  77. function_entry car_methods[] = {
  78.     PHP_ME(Car,  __construct,     NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
  79.     PHP_ME(Car,  shift,           NULL, ZEND_ACC_PUBLIC)
  80.     PHP_ME(Car,  accelerate,      NULL, ZEND_ACC_PUBLIC)
  81.     PHP_ME(Car,  brake,           NULL, ZEND_ACC_PUBLIC)
  82.     PHP_ME(Car,  getCurrentSpeed, NULL, ZEND_ACC_PUBLIC)
  83.     PHP_ME(Car,  getCurrentGear,  NULL, ZEND_ACC_PUBLIC)
  84.     {NULL, NULL, NULL}
  85. };


  86. PHP_MINIT_FUNCTION(vehicles)
  87. {
  88.     zend_class_entry ce;
  89.     INIT_CLASS_ENTRY(ce, "Car", car_methods);
  90.     car_ce = zend_register_internal_class(&ce TSRMLS_CC);
  91.     car_ce->create_object = car_create_handler;
  92.     memcpy(&car_object_handlers,
  93.         zend_get_std_object_handlers(), sizeof(zend_object_handlers));
  94.     car_object_handlers.clone_obj = NULL;
  95.     return SUCCESS;
  96. }

  97. zend_module_entry vehicles_module_entry = {
  98. #if ZEND_MODULE_API_NO >= 20010901
  99.     STANDARD_MODULE_HEADER,
  100. #endif
  101.     PHP_VEHICLES_EXTNAME,
  102.     NULL,        /* Functions */
  103.     PHP_MINIT(vehicles),        /* MINIT */
  104.     NULL,        /* MSHUTDOWN */
  105.     NULL,        /* RINIT */
  106.     NULL,        /* RSHUTDOWN */
  107.     NULL,        /* MINFO */
  108. #if ZEND_MODULE_API_NO >= 20010901
  109.     PHP_VEHICLES_EXTVER,
  110. #endif
  111.     STANDARD_MODULE_PROPERTIES
  112. };

  113. #ifdef COMPILE_DL_VEHICLES
  114. extern "C" {
  115. ZEND_GET_MODULE(vehicles)
  116. }
  117. #endif
复制代码


car.h:

  1. #ifndef VEHICLES_CAR_H
  2. #define VEHICLES_CAR_H

  3. // A very simple car class
  4. class Car {
  5. public:
  6.     Car(int maxGear);
  7.     void shift(int gear);
  8.     void accelerate();
  9.     void brake();
  10.     int getCurrentSpeed();
  11.     int getCurrentGear();
  12. private:
  13.     int maxGear;
  14.     int currentGear;
  15.     int speed;
  16. };

  17. #endif /* VEHICLES_CAR_H */
复制代码


car.c

  1. #include "car.h"

  2. Car::Car(int maxGear) {
  3.     this->maxGear = maxGear;
  4.     this->currentGear = 1;
  5.     this->speed = 0;
  6. }

  7. void Car::shift(int gear) {
  8.     if (gear < 1 || gear > maxGear) {
  9.         return;
  10.     }
  11.     currentGear = gear;
  12. }

  13. void Car::accelerate() {
  14.     speed += (5 * this->getCurrentGear());
  15. }

  16. void Car::brake() {
  17.     speed -= (5 * this->getCurrentGear());
  18. }

  19. int Car::getCurrentSpeed() {
  20.     return speed;
  21. }

  22. int Car::getCurrentGear() {
  23.     return currentGear;
  24. }
复制代码


3 修改config.m4文件:

config.m4:

  1. PHP_ARG_ENABLE(vehicles,
  2.     [Whether to enable the "vehicles" extension],
  3.     [  --enable-vehicles      Enable "vehicles" extension support])

  4. if test $PHP_VEHICLES != "no"; then
  5.     PHP_REQUIRE_CXX()
  6.     PHP_SUBST(VEHICLES_SHARED_LIBADD)
  7.     PHP_ADD_LIBRARY(stdc++, 1, VEHICLES_SHARED_LIBADD)
  8.     PHP_NEW_EXTENSION(vehicles, vehicles.cc car.cc, $ext_shared)
  9. fi
复制代码


4 phpize

5 ./configure --enable-vehicles

6 make
  在这里编译过了, 但有几个warnning, 关于char*类型转换的. 不会因为几个warnning的问题吧??

7 make install
  nstalling shared extensions:     /usr/local/lib/php/extensions/no-debug-non-zts-20090626/

8 我把刚才编译的vehicles整个目录copy到/var/www/下.

9 修改php.ini:
  emacs /etc/php5/apache2/php.ini
在里面加入extension=vehicles, 并把 enable_dl设置为On

10 重启apache2

11 在浏览器里输入http://localhost/vehicles/vehicles.php出现以下错误:

Warning: dl() [function.dl]: vehicles: Unable to initialize module Module compiled with module API=20090626, debug=0, thread-safety=0 PHP compiled with module API=20060613, debug=0, thread-safety=0 These options need to match in /var/www/vehicles/vehicles.php on line 5
Functions available in the test extension:

Warning: Invalid argument supplied for foreach() in /var/www/vehicles/vehicles.php on line 10

Module vehicles is not compiled into PHP

网上找了很多资料都没说这个问题, 我该怎么解决?

论坛徽章:
0
10 [报告]
发表于 2009-09-07 13:40 |只看该作者
我用楼上的代码试了一下的却可以,然后自己用 vehicles 这个名字试了一下真是可以的。然后我随便换个abcd就报错了HP Warning:  dl(): Unable to load dynamic library './abcd.so' - ./abcd.so: undefined symbol: __gxx_personality_v0 in /opt/software/php-5.2.8/ext/abcd/abcd.php on line 5

Warning: dl(): Unable to load dynamic library './abcd.so' - ./abcd.so: undefined symbol: __gxx_personality_v0 in /opt/software/php-5.2.8/ext/abcd/abcd.php on line 5

所有操作都一样。真是怪了。
[root@mail abcd]# phpize -v
Configuring for:
PHP Api Version:         20041225
Zend Module Api No:      20060613
Zend Extension Api No:   220060519
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP