PHP Extension&Makefile作成
5356 ワード
PHP Extensionって何ですか?多くのPHPを書くエンジニアは、PHP Extensionがどのようにして作られたのか分からないかもしれませんが、実はPHPの最下層はc言語を使っています.すべてのPHPの文法は、c言語を通じて実現されています.だから、私たちはcを通じて、PHPの機能を強化することができます.PHPをもっと使いやすくすることができます.正常なPHP Extensionを作るときは、まずconfigを書きます.m 4このファイル、このファイルは難しくありませんが、彼とMakefileのフォーマットの落差はとても大きいです.ここではMakefileを使ってPHP Extensionをコンパイルする方法を紹介します.まず、正常なPHP Extensionコンパイルの流れを紹介します.phpizeはMakefileファイルを構築します.configureこのコマンドは関連パッケージがインストールされているかどうかを自動的にチェックします c codeとconfigを確立する.m4 phpize(下Linux指令phpize) ./configure make mv modules/xxx.so/extension:コンパイルされたsoファイルをextensionディレクトリの下に移動し、PHP Extension を完了しても
php extension Makefileの作成
基本phpizeの動作はMakefile,libtoolなどのツールを構築することです./configureは、いくつかの設定が正常かどうか、パス設定をチェックすることです.つまり、php extensionを自分で書く必要があります.では、この2つのプロセスをスキップして、Makefileを自分で書きましょう.まずphpizeを使用して、自動的にMakefileを生成し、それから彼を私たちが望んでいるフォーマットに変更します. phpize & mv Makefile Makefile.Global:MakefileをMakefileに変更します.global
Makefile.を修正する私たちが望むようにglobalの例 phpインストールディレクトリPHP_を追加DIR=/home/program/php(パスは自分で変更しましょう) 部分変数の値をPHP_に変更DIR、例えばprefix=$(PHP_DIR)、phpincludedir=$(PHP_DIR)/include/php phplibdir=$(SRC_PATH)/modules:コンパイル完了後、soファイルのパス を指定 PHP_PECL_EXTENSION=extension name//(名前が重複しないように注意) srcdir , builddir , top_srcdir , top_builddir、現在のディレクトリに変更し、絶対ディレクトリ を使用します.
簡略化されたMakefile
Makefile.globalは半日やって、最後にやっと簡略化して完成して、後でphp extensionをコンパイルするのはずっと便利で、正式にプログラムをコンパイルするためのMakefileを書いて、見て!次のPHP Makefileはどんなに短いか.
Example
makeの結果
Example
phpが伝達する変数を受信する方法zend_を使用parseのfunctionには、[sal,lsl]が接続する変数の型を表す2つがあります. zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"sal",xxx,xx) zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,num_args TSRMLS_CC,"lsl", xx,xx,xx,xx) l:long を表す s : string a : array b : boolean d : double resultをphpに返信する方法は以下のいくつかの がある. RETURN_LONG:回送long RETURN_STRING:回送文字列 RETURN_DOUBLE:エコー倍精数 RETURN_BOOL:回伝boolean(true or false) php extension functionを確立する
extension functionと書くにはPHP_を使いますFUNCTIONというfunctionですが、最初のパラメータはfunction名で、書き終わったらphpでsimple(「xxx」)を使うことができます.
Example
第2の例はfunction entryで定義されたaddであり、主な機能は第1のパラメータと第2のパラメータを合計する機能であり、php extensionではすべてのデジタル破壊はRETURN_を使用するLONGは,int,long,floatに基づいてリターン値を判断する必要はないが,php変数の型態が自由であるため,こんなに細かく区別する必要はない.
Example
関連する問題
warning: deprecated conversion from string constant to 'char*'
私はgcc 4.2をアップグレードします.0後、コンパイルするとこのWarningが現れ、gcc 3.4を使用する.6大丈夫です.
第2手、Warningに出会って止まらないで、Makefileファイルの中で、-Werrorのこの属性を取りましょう
undefined symbol:__gxx_personality_v0
c++構文を使用しているため、c++のlibraryはロードされていません.
解法:MakefileのCCに-lstdc++を加え、これを加えるとコンパイル時に/usr/lib/libstdc++が自動的にロードされます.so.
Example
エラー:Invalid library(maybe not a PHP library)の処理
これは、phpがsoファイルをロードすると、プログラムエントリが見つかりません.c&c++のプログラムエントリはmainですが、php extensionのプログラムエントリはzend_です.module_entryですが、私はc++文法を使っているので、c++には特性があり、コンパイル時に数やfunction名を自動的に変更します.
Example
このような文法は、c++コンパイル後、MyExtension_になる可能性があります.module_entryii,結果としてプログラムエントリが見つからずエラーを報告する.
解法はextern「C」を追加することです
Example
なぜextern「C」をつけるのですか?
C++にはoverloadingの機能があることを知っています.一つのfunctionにはいろいろなパラメータの数がありますが、c++はどうやってできますか.実は彼はプログラムをコンパイルするとき、自動的にfunction nameのmappingをします.例えば、次の例ですが、単純なc言語ではこれが分からないので、c言語がc++のfunctionを読み取るとき、extern「C」を付けて、c++に名前をむやみに変更しないように強制しなければならない.そうすれば、c言語はfunctionを正しく実行することができる.
Example
php extension Makefileの作成
基本phpizeの動作はMakefile,libtoolなどのツールを構築することです./configureは、いくつかの設定が正常かどうか、パス設定をチェックすることです.つまり、php extensionを自分で書く必要があります.では、この2つのプロセスをスキップして、Makefileを自分で書きましょう.
Makefile.を修正する私たちが望むようにglobalの例
簡略化されたMakefile
Makefile.globalは半日やって、最後にやっと簡略化して完成して、後でphp extensionをコンパイルするのはずっと便利で、正式にプログラムをコンパイルするためのMakefileを書いて、見て!次のPHP Makefileはどんなに短いか.
Example
SRC_PATH = $ ( shell pwd )
LDEF = - DCOMPILE_DL_MyExtension
CXXFILE = myClass . cc extension . cc
EXTRA_CXXFLAGS =
CXXOUTPUT = MyExtension
include Makefile . global
cp :
sudo cp ./ modules / $ ( CXXOUTPUT ). so / home / php_extension /
makeの結果
Example
create myClass . lo
create myClass . o
create extension . lo
create extension . o
create MyExtension . la
create MyExtension . so
// MyExtension.so
phpが伝達する変数を受信する方法zend_を使用parseのfunctionには、[sal,lsl]が接続する変数の型を表す2つがあります.
extension functionと書くにはPHP_を使いますFUNCTIONというfunctionですが、最初のパラメータはfunction名で、書き終わったらphpでsimple(「xxx」)を使うことができます.
Example
PHP_FUNCTION ( simple )
{
char * str = NULL ;
char * tmp = new char [ 50 ];
string result = "" ;
int str_len = 0 ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS () TSRMLS_CC ,
"s" ,
& str ,& str_len ) == FAILURE ) {
RETURN_NULL ();
}
sprintf ( tmp , "Your input string is [%s]" , str );
result = tmp ;
delete [] tmp ;
RETURN_STRING ( const_cast < char *>( result . c_str ()), 1 );
}
第2の例はfunction entryで定義されたaddであり、主な機能は第1のパラメータと第2のパラメータを合計する機能であり、php extensionではすべてのデジタル破壊はRETURN_を使用するLONGは,int,long,floatに基づいてリターン値を判断する必要はないが,php変数の型態が自由であるため,こんなに細かく区別する必要はない.
Example
PHP_FUNCTION ( add )
{
int num_args = ZEND_NUM_ARGS ();
if ( num_args != 2 ) {
RETURN_LONG ( 0 );
}
int result = 0 , int1 , int2 ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS () TSRMLS_CC ,
"ll" ,
& int1 ,& int2 ) == FAILURE ) {
RETURN_NULL ();
}
result = int1 + int2 ;
RETURN_LONG ( result );
}
関連する問題
warning: deprecated conversion from string constant to 'char*'
私はgcc 4.2をアップグレードします.0後、コンパイルするとこのWarningが現れ、gcc 3.4を使用する.6大丈夫です.
第2手、Warningに出会って止まらないで、Makefileファイルの中で、-Werrorのこの属性を取りましょう
undefined symbol:__gxx_personality_v0
c++構文を使用しているため、c++のlibraryはロードされていません.
解法:MakefileのCCに-lstdc++を加え、これを加えるとコンパイル時に/usr/lib/libstdc++が自動的にロードされます.so.
Example
CC = cc - lstdc ++
エラー:Invalid library(maybe not a PHP library)の処理
これは、phpがsoファイルをロードすると、プログラムエントリが見つかりません.c&c++のプログラムエントリはmainですが、php extensionのプログラムエントリはzend_です.module_entryですが、私はc++文法を使っているので、c++には特性があり、コンパイル時に数やfunction名を自動的に変更します.
Example
zend_module_entry MyExtension_module_entry
このような文法は、c++コンパイル後、MyExtension_になる可能性があります.module_entryii,結果としてプログラムエントリが見つからずエラーを報告する.
解法はextern「C」を追加することです
Example
zend_module_entry MyExtension_module_entry = {
}
extern "C" {
ZEND_GET_MODULE ( MyExtension )
}
なぜextern「C」をつけるのですか?
C++にはoverloadingの機能があることを知っています.一つのfunctionにはいろいろなパラメータの数がありますが、c++はどうやってできますか.実は彼はプログラムをコンパイルするとき、自動的にfunction nameのmappingをします.例えば、次の例ですが、単純なc言語ではこれが分からないので、c言語がc++のfunctionを読み取るとき、extern「C」を付けて、c++に名前をむやみに変更しないように強制しなければならない.そうすれば、c言語はfunctionを正しく実行することができる.
Example
int test ( int a ){}
int test ( char b , char c ){}
//
test ( int a ) => test_1 ( int a )
test ( char b , char c ) => test_2 ( char b , char c )