利用php調用so庫文件中的代碼


某個功能被編譯到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 = 3, b = 4;
    printf("%d + %d = %d/n", a, b, hello_add(a,b));
    return 0;
}

 

編譯並執行:

$ gcc -o hellotest -lhello hellotest.c
$ ./hellotest
3 + 4 = 7

 

OK,下面我們來制作PHP模塊。首先確保你安裝了 php-devel 包,沒有的話請自行從安裝光盤上找。然后下載php源代碼。我使用的是php-5.2.3.tar.gz,解壓縮。

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

 

然后通過下面的命令建立一個名為 hello 的模塊。

$ ./ext_skel --extname=hello

 

執行該命令之后它會提示你應當用什么命令來編譯模塊,可惜那是將模塊集成到php內部的編譯方法。如果要編譯成可動態加載的 php_hello.so,方法要更為簡單。

$ cd hello

首先編輯 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])

 

然后執行 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,則說明函數調用成功了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM