同事拿C寫了個東東,PHP不能直接用,便問他可否寫個擴展,他於是提到SWIG,我想來慚愧,我寫過的幾個擴展,全部用的是PHP源碼包中自帶的ext_skel,於是開始學習了下SWIG。
swig是個好東東,可以把C包裝成各種擴展,java/perl/python,詳情可參見swig官網 http://www.swig.org/,可下載其最新版本,安裝也非常簡單,解壓,./configure && make && makeinstall,有手就會。但教程中,只舉例了java/perl等等,未發現PHP的影子,但根據其介紹,擴展php肯定是不成問題的,於是繼續搜索,終於依靠我淺薄的C知識加上官網手冊,用swig生成了PHP的擴展。
具體步驟:
1、先寫個c文件,example.c
/* File : example.c */ #include <time.h> double My_variable = 3.0; int fact(int n) { if (n <= 1) return 1; else return n*fact(n-1); } int my_mod(int x, int y) { return (x%y); } char *get_time() { time_t ltime; time(<ime); return ctime(<ime); }
2、寫一個接口文件(interface file)投入到swig中。example.i
/* example.i */ %module example %{ /* Put header files here or function declarations like below */ extern double My_variable; extern int fact(int n); extern int my_mod(int x, int y); extern char *get_time(); %} extern double My_variable; extern int fact(int n); extern int my_mod(int x, int y); extern char *get_time();
3、建立PHP模塊
swig -php example.i
這時可以看到生成了example.php example_wrap.c php_example.h這三個文件,我們vim example.php,可以看到這裏將c文件中定義的函數都轉化成了class example的靜態函數,而且,example.php會先判斷是否已load了example.so以及根據不同的OS來動態的引入該so。example_warp.c是根據要建立的擴展語言的不同而變化的,這裏都是PHP和zend的一些宏
gcc -fpic -c example.c
生成了example.o,PIC是Position-IndependentCode的縮寫,因爲動態鏈接庫就是爲了實現位置無關,所以需要使用-fPIC.
gcc `php-config --includes` -fpic -c example_wrap.c
生成了example_wrap.o.`php-config --includes`是把php依賴的頭文件路徑全部獲取
gcc -shared *.o -o example.so -I/usr/local/share
生成了example.so
cp example.so `php-config --extension-dir`
php的擴展路徑中就會有該so了
4使用該擴展
方法1:
vim code.php
<?php
include "example.php";
echo example::get_time();
?>
注意:現在這個example.php派上用場了。然後再php code.php,怎麼樣,看見當前時間了嗎?
方法2:
<?php
dl("example.so");
echo get_time();
?>