某个功能被编译到so文件中,那么如何通过php来调用它?一个方法是写一个php模块(php extension),在php中调用该模块内的函数,再通过该模块来调用so中的函数。下面做一个简单的例子,使用的操作系统是RHEL5。

首先做一个简单的so文件:

/**
* hello.c
* To compile, use following commands:
* gcc -O -c -fPIC -o hello.o hello.c
* gcc -shared -o libhello.so hello.o
*/ int hello_add(int a, int b)
{
return a + b;
}

然后将它编译成.so文件并放到系统中:

$ gcc -O -c -fPIC -o hello.o hello.c
$ gcc -shared -o libhello.so hello.o
$ su
# echo /usr/local/lib > /etc/ld.so.conf.d/local.conf
# cp libhello.so /usr/local/lib
# /sbin/ldconfig

写段小程序来验证其正确性:

/**
* hellotest.c
* To compile, use following commands:
* gcc -o hellotest -lhello hellotest.c
*/
#i nclude <stdio.h>
int main()
{
int a = , b = ;
printf("%d + %d = %d/n", a, b, hello_add(a,b));
return ;
}

编译并执行:

$ gcc -o hellotest -lhello hellotest.c
$ ./hellotest
+ =

OK,下面我们来制作PHP模块。首先确保你安装了 php-devel 包,没有的话请自行从安装光盘上找。然后下载php源代码。我使用的是php-5.2.3.tar.gz,解压缩。

$ tar xzvf php-5.2..tar.gz
$ cd php-5.2./ext

然后通过下面的命令建立一个名为 hello 的模块。

$ ./ext_skel --extname=hello

执行该命令之后它会提示你应当用什么命令来编译模块,可惜那是将模块集成到php内部的编译方法。如果要编译成可动态加载的 php_hello.so,方法要更为简单。

$ cd hello

首先编辑 config.m4 文件,去掉第16行和第18行的注释(注释符号为 dnl 。)

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

然后执行 phpize 程序,生成configure脚本:

$ phpize

然后打开 php_hello.h,在 PHP_FUNCTION(confirm_hello_compiled); 之下加入函数声明:

PHP_FUNCTION(confirm_hello_compiled);   /* For testing, remove later. */
PHP_FUNCTION(hello_add);

打开 hello.c,在 PHP_FE(confirm_hello_compiled, NULL) 下方加入以下内容。

zend_function_entry hello_functions[] = {
PHP_FE(confirm_hello_compiled, NULL) /* For testing, remove later. */
PHP_FE(hello_add, NULL) /* For testing, remove later. */
{NULL, NULL, NULL} /* Must be the last line in hello_functions[] */
};

然后在 hello.c 的最末尾书写hello_add函数的内容:

PHP_FUNCTION(hello_add)
{
long int a, b;
long int result; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &a, &b) == FAILURE) {
return;
} result = hello_add(a, b); RETURN_LONG(result);
}

保存退出,编译并安装:

$ ./configure
$ make LDFLAGS=-lhello
$ su
# cp modules/hello.so /usr/lib/php/modules

然后在 /var/www/html 下建立一个 hello.php 文件,内容如下:

<?php
dl("hello.so");
echo hello_add(3, 4);
?>

然后在浏览器中打开hello.php文件,如果显示7,则说明函数调用成功了。

利用php调用so库文件中的代码的更多相关文章

  1. python调用另一个文件中的代码,pycharm环境下:同文件夹下文件(.py)之间的调用,出现红线问题

    如何调用另一个python文件中的代码无论我们选择用何种语言进行程序设计时,都不可能只有一个文件(除了“hello world”),通常情况下,我们都需要在一个文件中调用另外一个文件的函数呀数据等等, ...

  2. [置顶] android利用jni调用第三方库——第三篇——编写库android程序整合第三方库libhello.so到自己的库libhelloword.so

    0:前言: 在第二篇中,我们主要介绍了丙方android公司利用乙方C++公司给的动态库,直接调用库中的方法,但是这样方式受限于: 乙方C++公司开发的动态库是否符合jni的规范,如果不规范,则不能直 ...

  3. [置顶] android利用jni调用第三方库——第二篇——编写库android程序直接调用第三方库libhello.so

    0:前言 1:本文主要作为丙方android公司的身份来写 2:作者有不对的地方,请指出,谢谢 [第一篇:android利用jni调用第三方库——编写库libhello.so] [第二篇:androi ...

  4. Delphi COM编程技术三类型库(库文件中的工具栏,很全)

    在COM组件的使用和开发过程中经常需要获取有关组件的信息.而COM组件以二进制代码的形式发布,如果不借助特定的工具这些相关信息将难以被获取.通过访问类型库就可以查看COM组件的信息. 一.类型库的基础 ...

  5. 查看Linux下*.a库文件中文件、函数、变量

    查看Linux下*.a库文件中文件.函数.变量等情况在Linux 下经常需要链接一些 *.a的库文件,那怎么查看这些*.a 中包 含哪些文件.函数.变量: 1. 查看文件:ar -t xxx.a 2. ...

  6. 如何调用另一个python文件中的代码

    模块的搜索路径 模块的搜索路径都放在了sys.path列表中,如果缺省的sys.path中没有含有自己的模块或包的路径,可以动态的加入(sys.path.apend)即可.下面是sys.path在Wi ...

  7. 查看Linux下*.a库文件中文件、函数、变量等情况

    在Linux 下经常需要链接一些 *.a的库文件,那怎么查看这些*.a 中包 含哪些文件.函数.变量: 1. 查看文件:ar -t *.a 2. 查看函数.变里:nm *.a

  8. python中一个py文件如何调用其他py文件中的类和函数

    HelloWorld  文件名称  Hello是类 from HelloWorld import Hello >>> h = Hello() >>> h.hello ...

  9. 利用ROS工具从bag文件中提取图片

    bag文件是ROS常用的数据存储格式,因此要从bag文件中提取数据就需要了解一点ROS的背景知识. 1. 什么是ROS及其优势 ROS全称Robot Operating System,是BSD-lic ...

随机推荐

  1. hdu 1423 最长上升递增子序列

    #include <iostream> #include <cstdio> #include <cstring> using namespace std; ; in ...

  2. [CODEVS1130]数字反转

    题目描述 Description 给定一个整数,请将该数各个位上数字反转得到一个新数.新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零. 这是一道水题.我必须 ...

  3. 用正则表达式模仿Mustache插件的功能

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...

  4. jsp和java获取文件或路径

    1.如何获得当前文件路径常用:(1).Test.class.getResource("")得到的是当前类FileTest.class文件的URI目录.不包括自己!(2).Test. ...

  5. 归并排序Merge sort(转)

    原理,把原始数组分成若干子数组,对每一个子数组进行排序, 继续把子数组与子数组合并,合并后仍然有序,直到全部合并完,形成有序的数组 举例 无序数组[6 2 4 1 5 9] 先看一下每个步骤下的状态, ...

  6. 開關(switch)規格中,SPDT, DPDT, 3PDT, 4PDT是什麼意思?

    Reference http://blog.xuite.net/auster.lai/twblog/433393966 開關(switch)用來控制電路的開與閉,機械式的switc內部是由接點開關.彈 ...

  7. solr6.6安装

    1. 确保系统已经安装jdk1.8,以及Tomcat8. 注:使用Tomcat7会出现很多问题,我遇到的是直接打不开solr的index页面,看网上有网友说还会遇到各种css.js资源404..还有l ...

  8. poj 3169&hdu3592(差分约束)

    Layout Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9687   Accepted: 4647 Descriptio ...

  9. springBoot 定时器

    程序入口类中加入注解 @EnableScheduling 配置定时任务为并行 @Slf4j @Configuration public class ScheduledConfig implements ...

  10. Codeforces 912D Fishes (概率&期望,优先队列的应用)

    题目链接 Fishes 题意  在一个$n*m$的矩阵中,随机选择一个$r * r$的区域覆盖. 一开始我们可以在这个$n*m$的矩阵中选择$k$个点标记为$1$. 我们要选择一个最佳的标记策略,使得 ...