lunix 下php调用c/c++的.so动态链接库

1,下载lunix系统同版本PHP源码安装包并解压:将源码下载解压到系统中即可,不用刻意位置。

       wget http://cn2.php.net/distributions/php-5.4.45.tar.gz

2,解压     tar -zxvf php-5.4.45.tar.gz

3.到 /php-5.4.45/ext/ 目录下,使用ext_skel生成扩展骨架: 即生成名为test的模块。

cd www/wwwroot/1001/php-5.4.45/ext 

./ext_skel --extname=test

4.修改配置文件 /test/config.m4

取消下面两行(16.18行)的dnl注释:

PHP_ARG_ENABLE(test, whether to enable test support,
dnl Make sure that the comment is aligned:
[  --enable-test           Enable test support])

如果要使用C++进行编译,要将test.c改名为test.cpp,并在config.m4中添加

PHP_REQUIRE_CXX()    
PHP_ADD_LIBRARY(stdc++, 1, EXTRA_LDFLAGS)
PHP_NEW_EXTENSION(test, test.cpp, $ext_shared)

5.在php_test.h文件中添加代码,加入自定义的函数声明:函数名为testFunc,函数名不同时注意修改

PHP_MINIT_FUNCTION(test);
PHP_MSHUTDOWN_FUNCTION(test);
PHP_RINIT_FUNCTION(test);
PHP_RSHUTDOWN_FUNCTION(test);
PHP_MINFO_FUNCTION(test);

PHP_FUNCTION(confirm_test_compiled);	/* For testing, remove later. */
PHP_FUNCTION(testFunc);

6.在test.c/cpp中添加自定义函数代码:

(1)首先,在这个位置引入用到的头文件:

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdio.h>
#include <string.h>
#include <math.h>

#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "php_test.h"

(2)然后,在这个位置添加函数testFunc入口:函数名不同时注意修改函数名

const zend_function_entry test_functions[] = {
	PHP_FE(confirm_test_compiled, NULL)		/* For testing, remove later. */
	PHP_FE(testFunc, NULL)
	PHP_FE_END	/* Must be the last line in test_functions[] */
};

(3)最后,在文件尾部添加testFunc函数的代码,也可以在这里定义其他自定义函数,函数名不同时注意修改函数名

PHP_FUNCTION(testFunc)  
{  
    char *x = NULL;  
    char *y = NULL;  
    int argc = ZEND_NUM_ARGS();  
    int x_len;  
    int y_len;  
  
    if (zend_parse_parameters(argc TSRMLS_CC, "ss", &x, &x_len, &y, &y_len) == FAILURE)   
        return;  
      
    int result_length = x_len + y_len;  
    char* result = (char *) emalloc(result_length + 1);  
    strcpy(result, x);  
    strcat(result, y);  
  
    RETURN_STRINGL(result, result_length, 0);  
}  

7.在 /root/php-5.4.45/ext/test/ 目录下,建立php扩展模块

phpize

可能需要加上路径:

/usr/local/php/bin/phpize

8.回到 /root/php-5.4.45/ 目录,重新建立编译需要的配置:

cd ../..
./buildconf --force

若出现类似的报错:

buildconf: You need autoconf 2.59 or lower to build this version of PHP.
          You are currently trying to use 2.63
          Most distros have separate autoconf 2.13 or 2.59 packages.
          On Debian/Ubuntu both autoconf2.13 and autoconf2.59 packages exist.
          Install autoconf2.13 and set the PHP_AUTOCONF env var to
          autoconf2.13 and try again.

那么,通过下面的方法解决:

yum install autoconf213
export PHP_AUTOCONF=/usr/bin/autoconf-2.13

9.再到 /root/php-5.4.45/ext/test/ 目录下,生成配置: 注意php-config 的位置,可使用命令find / -name php-config 进行查询。(222.28.39.217:2025/2027系统下php-config文件位置为:/www/server/php/54/bin,即命令改为./configure --with-php-config=/www/server/php/54/bin/php-config)

./configure --with-php-config=/usr/local/php/bin/php-config

10.编译并生成.so扩展文件

make
make install

若make出错,修改代码直到编译通过

若make install出错,修改后,需要清空当前生成的扩展模块:

phpize --clean

然后从第7步重新开始

11.查看test.so是否生成

make install成功后会给出生成路径,例如:/usr/local/php/lib/php/extensions/no-debug-non-zts-20131226/test.so

12.修改php.ini,注意php.ini文件的位置

修改 /www/server/php/54/etc/php.ini 文件,加入扩展路径和名称:

约在php.ini文件722行位置添加:extension_dir = "/www/server/php/54/lib/php/extensions/no-debug-non-zts-20100525/" 

在php.ini文件最后位置添加:extension = "test.so"

extension_dir = "/usr/local/php/lib/php/extensions/no-debug-non-zts-20131226/"

extension = "teste.so"

13.重启PHP服务

service php-fpm restart

14.在PHP中使用C++扩展函数

<?php 
$concat_str = testFunc("concat1","concat2");
echo $concat_str;
?>

分析:使用宝塔或是lnmp无人值守安装Lunix系统环境时,php中没有ext_skel脚本,因此要在php扩展库中添加该脚本,但是该脚本依赖于php的其他脚本,因此将lunix环境php相同版本的源码下载至环境中,在下载的php源码包中设置函数,即步骤1-10。步骤9,步骤12 要注意php.config/php.ini 文件的位置,这两步即是将自己写的so扩展库写入php,用以使用。

另:在步骤6中将testFunc函数声明定义,若要在外部进行定义,需要外部生成so文件,并调用该so文件,步骤如下:

/*创建外部链接库.so*/
    1.新建.c文件;
    2.在文件中写库函数;
        如:
            int hello_add(int a, int b)
        {
            return a + b;
        }
    3.将.c文件编译为.so;
        gcc -O -c -fPIC -o hello.o hello.c
        gcc -shared -o libhello.so hello.o
        [hello为文件名或库名]
    4.将此库加入到系统库中;
        echo /usr/local/lib > /etc/ld.so.conf.d/local.conf
        cp libhello.so /usr/local/lib
        /sbin/ldconfig
        完成外部库创建
/*创建外部链接库.so*/

/*创建php链接库.so*/
    1.确保安装了 php-devel 包;
    2.下载对应系统php版本的php包;
        下载地址:http://php.net/releases/
        下载方法[版本号直接在链接修改]:wget http://cn2.php.net/distributions/php-7.0.2.tar.gz
    3.解压安装包,进入包内的ext目录;
    4.生产扩展开发环境[环境名称hello可修改]:
        ./ext_skel --extname=hello
    5.进入生成的目录,找到config.m4,编辑,修改16行和18行(去掉行首的dnl);
        16行:  PHP_ARG_ENABLE(hello, whether to enable hello support,
        17行:  dnl Make sure that the comment is aligned:
        18行:  [  --enable-hello           Enable hello support])
    6.找到.h的文件;
        在  PHP_FUNCTION(confirm_test_compiled);    /* For testing, remove later. */  这一行下方添加:
        PHP_FUNCTION(testFunc);
        其中testFunc是准备在php中使用的函数名;
    7.找到.c文件;
        const zend_function_entry test_functions[] = {
            PHP_FE(confirm_test_compiled, NULL)        /* For testing, remove later. */
            PHP_FE(testFunc, NULL)  /*这一行新增,testFunc与6中一致*/
            PHP_FE_END    /* Must be the last line in test_functions[] */
        };
        在文件末尾添加函数定义:
        PHP_FUNCTION(testFunc) /*此处函数名需要与上面一致*/
        {
            long int a, b;    /*此处声明php的传入参数*/
            long int result;    /*此处声明(运算后)返回给php的参数*/
            if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &a, &b) == FAILURE) {/*此处加入传入参数的引用*/
                return;
            }
            result = hello_add(a, b);  /*此处调用的函数为外部链接库中的函数*/
            RETURN_LONG(result); /*此处将运算结果返回给php */
        }    
    8.执行(在环境目录hello下) phpize;
    9.执行(返回到php文件夹) ./buildconf --force;
    10.执行(在环境目录hello下)[config需要根据实际情况修改为本系统的php-config目录] 
        ./configure --with-php-config=/usr/local/php/bin/php-config
    11.执行 make LDFLAGS=-lhello  /*其中hello为外部库的名称,若不连接外部库,则直接执行make即可*/;
    12.执行 make install;
    13.找到php.ini,新增:
        extension_dir = "/usr/local/php/lib/php/extensions/no-debug-non-zts-20131226/" #这句话为.so文件放置目录
        extension = "hello.so"   #这句话为.so文件
    14.重启环境;
    15.在新建的php文件中直接使用testFunc()函数(其中的参数需要与7中的一致);

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值