ホームページ バックエンド開発 PHPチュートリアル php_PHPチュートリアルでCコードを呼び出す実装方法

php_PHPチュートリアルでCコードを呼び出す実装方法

Jul 13, 2016 am 10:36 AM
php 呼び出しメソッド

C コードは php プログラムで使用する必要があり、次の 2 つの状況で使用する必要があります:

1 すでに C コードがあり、それを PHP プログラムで直接使用したいです
2 PHP のパフォーマンスの問題により、一部の関数を実装するには C を使用する必要があります

最初のケースでは、システム コールを使用して既存の C コードを独立したプログラムに書き込むのが最も適切な方法です。パラメーターはコマンド ラインまたは標準入力を通じて渡され、結果は標準出力から読み取られます。次に、少し面倒な方法は、C コードをデーモンとして記述し、PHP プログラムがソケットを使用してデーモンと通信することです。

2 番目のケースに注目してください。システム コール方式を使用することもできますが、多くのプロセスを頻繁に起動すると、当然ながらパフォーマンスが低下することを考慮してください。デーモンを作成する方法は確かに実行可能ですが、はるかに複雑です。

私の簡単なテストでは、同じアルゴリズムが PHP よりも C で書かれた方が 500 倍効率的であることがわかりました。また、PHP 拡張機能を使用すると、90 倍以上改善することもできます (パフォーマンスの低下はパラメーターの受け渡しにあると思います)。

そのため、php 拡張機能が最良の選択となる場合もあります。

ここでは、PHP を再コンパイルせずに C で PHP 拡張機能を記述する方法に焦点を当てます。

まず、PHP ソース コードを見つけます。これは、ターゲット プラットフォームの PHP バージョンとは関係ありません。

ソースコードの ext ディレクトリに ext_skel という名前のスクリプトがあります (Windows プラットフォームでは ext_skel_win32.php を使用します)
このディレクトリで ./ext_skel --extname=hello を実行します (例として hello を使用します)
ディレクトリが生成されます現時点では、ディレクトリ内にいくつかのファイルがあります。config.m4 hello.c php_hello.h

の 3 つだけを気にする必要があります。

このディレクトリを任意の場所にコピーし、そこに cd して、
phpize
/configure
make
を実行しても何も起こりませんよね?
これは手順を見逃したためです。config.m4 を開いて次の
dnl を見つけます。拡張機能が外部のものを参照している場合は、with:
..
dnl を使用します。それ以外の場合は、enable:
..
を使用します。これは拡張機能を選択するためのものです。で使用する または有効にして、使用しましょう。 with 部分のコメントを解除します。
私と同じように vim エディターを使用している場合は、3 文字の dnl が元々コメントを表していることが簡単にわかるでしょう (これは、vim にはデフォルトでさまざまなファイル形式用の構文カラーリング パッケージが付属しているためです)

config.m4 を変更したら、
phpize
/configure
make
を続けます。このとき、モジュールの下に hello.so および hello.la ファイルが生成されます。 1 つは動的ライブラリで、もう 1 つは静的ライブラリです。

php 拡張機能は準備ができていますが、まだ必要な機能を実現していません。まず、この拡張機能の使用方法について説明します。 ext_skel は呼び出し例を使用して hello.php を生成しましたが、その例では hello.so を PHP の拡張ディレクトリにコピーする必要があります。私たちは独自の関数を実装したいだけであり、PHP のコピーバージョンを作成したくありません。代わりに、次を使用してロードします:

コードをコピーします コードは次のとおりです:

if(!extension_loaded("hello")) {
dl_local("hello.so");
}
function dl_local( $extensionFile ) {
//ライブラリをロードできることを確認します06。        if( !(bool)ini_get( "enable_dl" ) || (bool)ini_get( "safe_mode" ) ) {
die( "dh_local(): 拡張機能の読み込みは許可されていません。/n" );
}
//checkファイルが存在することを確認します11。        if( !file_exists(dirname(__FILE__) . "/". $extensionFile ) ) {
die( "dl_local(): ファイル '$extensionFile' が存在しません。/n" );
}
// ファイルのアクセス許可を確認します16 。        if( !is_executable(dirname(__FILE__) . "/". $extensionFile ) ) {
die( "dl_local(): ファイル '$extensionFile' は実行可能ではありません。/n" );
}
//パス21。        $currentDir = ディレクトリ名(__FILE__) 。 "/";
$currentExtPath = ini_get( "extension_dir" );
$subDirs = preg_match_all( "////" , $currentExtPath , $matches );
unset( $matches );
// 抽出したことを確認しましょう有効な拡張パス27。        if( !(bool)$subDirs ) {
die( "dl_local(): 有効な拡張パス [extension_dir] を決定できませんでした。/n" );
}
$extPathLastChar = strlen( $currentExtPath ) - 1;
もし( $extPathLastChar == strrpos( $currentExtPath , "/" ) ) {
$subDirs--;
}
$backDirStr = "";
for( $i = 1; $i $backDirStr .= "..";
if( $i != $subDirs ) {
$backDirStr .= "/";
}
}
//load46 への最終パスを構築します。        $finalExtPath = $backDirStr 。 $currentDir 。 $extensionFile;
//次に、dl() を実行して実際にモジュールをロードします49。        if( !dl( $finalExtPath ) ) {
die();
}
//モジュールが正しくロードされた場合は、モジュール名を取得する必要があります54。        $loadedExtensions = get_loaded_extensions();
$thisExtName = $loadedExtensions[ sizeof( $loadedExtensions ) - 1 ];
// 最後に、拡張機能名 58 を返します。        return $thisExtName;
}//end dl_local()

これの利点は、php 拡張機能が php コードに従うことができ、環境に優しい拡張機能であることです。

人々が次に懸念しているのは、関数を追加し、パラメーターの転送と戻り値を実装する方法です

関数を追加する手順は次のとおりです:
php_hello.h:
PHP_FUNCTION(confirm_hello_compiled) // 括弧内に関数名を入力します

hello.c
zend_function_entry hello_functions[] = {
PHP_FE(confirm_hello_compiled, NULL) /* ここに行を追加します*/
{NULL, NULL, NULL} /* hello_functions[] の最後の行である必要があります */
};
PHP_FUNCTION(confirm_hello_compiled)
{//ここに関数本体を記述します
}
実装される関数のプロトタイプは実際には同じです。さらに、hello_functions に次のことを示す情報が 1 行追加されます。この機能があります。

つまり、それらはすべて同じ関数プロトタイプを持っていますが、戻り値とパラメーターをどのように区別するのでしょうか?
例を示します:

コードをコピーします コードは次のとおりです:

PHP_FUNCTION(hello_strdiff)
{
char *r1 = NULL, *r2 = NULL;
int n = 0, m = 0; (i = 0; i for(j = 0; j for (i = 1; i for(j = 1; j if(r1[ i-1] == r2[j-1]) コスト = 0;
その他のコスト = 1; +1);
a = MIN(a, d[i-1][j-1]+コスト);
}


这是一个求两个字符串差异度的算法,输入参数两个字符串,返回整型。
参数的传递看这里
zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &r1, &n, &r2, &m)

把这个当成是scanf来理解好了。
类型说明见下表:

Boolean b zend_bool
Long l long
Double d double
String s char*, int
Resource r zval*
Array a zval*
Object o zval*
zval z zval*

如果想实现可选参数的话,例如一个字符串,一个浮点,再加一个可选的bool型,可以用"sd|b"来表示。
和scanf有一点不同的是,对于字符串,你要提供两个变量来存储,一个是char *,存字符串的地址,一个int,来存字符串的长度。这样有必要的时候,你可以安全的处理二进制数据。

那么返回值怎么办呢?
使用下面一组宏来表示:

RETURN_STRING
RETURN_LONG
RETURN_DOUBLE
RETURN_BOOL
RETURN_NULL

注意RETURN_STRING有两个参数
当你需要复制一份字符串时使用
RETURN_STRING("Hello World", 1);

否则使用
RETURN_STRING(str, 0);

这里涉及到了模块中内存的分配,当你申请的内存需要php程序中去释放的话,请参照如下表

Traditional Non-Persistent Persistent
malloc(count)
calloc(count, num)
emalloc(count)
ecalloc(count, num)
pemalloc(count, 1)*
pecalloc(count, num, 1)
strdup(str)
strndup(str, len)
estrdup(str)
estrndup(str, len)
pestrdup(str, 1)
pemalloc() & memcpy()
無料(ポイント) efree(ptr) pefree(ptr, 1)
realloc(ptr, newsize) errealloc(ptr, newsize) perrealloc(ptr, newsize, 1)
malloc(count * num + extr)** safe_emalloc(カウント、数値、拡張子) safe_pemalloc(count, num, extr)

通常は、「非永続的」にリストされているものを使用します。

基本的にはこれで、php 拡張機能の作成を開始できます。
今のアプリからは文字列操作ができれば十分なので、これくらいしか紹介できません。

www.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/740214.html技術記事 PHP プログラムで C コードを使用する必要がある場合は、次の 2 つの状況が考えられます。 1. すでに C コードがあり、それを PHP プログラムで直接使用したい場合 2. PHP のパフォーマンスの問題により、C コードを使用する必要がある場合。 C でいくつかの関数を実装します。
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Ubuntu および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド Ubuntu および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド Dec 24, 2024 pm 04:42 PM

PHP 8.4 では、いくつかの新機能、セキュリティの改善、パフォーマンスの改善が行われ、かなりの量の機能の非推奨と削除が行われています。 このガイドでは、Ubuntu、Debian、またはその派生版に PHP 8.4 をインストールする方法、または PHP 8.4 にアップグレードする方法について説明します。

CakePHP の日付と時刻 CakePHP の日付と時刻 Sep 10, 2024 pm 05:27 PM

Cakephp4 で日付と時刻を操作するには、利用可能な FrozenTime クラスを利用します。

CakePHP について話し合う CakePHP について話し合う Sep 10, 2024 pm 05:28 PM

CakePHP は、PHP 用のオープンソース フレームワークです。これは、アプリケーションの開発、展開、保守をより簡単にすることを目的としています。 CakePHP は、強力かつ理解しやすい MVC のようなアーキテクチャに基づいています。モデル、ビュー、コントローラー

CakePHP ファイルのアップロード CakePHP ファイルのアップロード Sep 10, 2024 pm 05:27 PM

ファイルのアップロードを行うには、フォーム ヘルパーを使用します。ここではファイルアップロードの例を示します。

CakePHP バリデータの作成 CakePHP バリデータの作成 Sep 10, 2024 pm 05:26 PM

Validator は、コントローラーに次の 2 行を追加することで作成できます。

PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法 PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法 Dec 20, 2024 am 11:31 AM

Visual Studio Code (VS Code とも呼ばれる) は、すべての主要なオペレーティング システムで利用できる無料のソース コード エディター (統合開発環境 (IDE)) です。 多くのプログラミング言語の拡張機能の大規模なコレクションを備えた VS Code は、

CakePHP クイックガイド CakePHP クイックガイド Sep 10, 2024 pm 05:27 PM

CakePHP はオープンソースの MVC フレームワークです。これにより、アプリケーションの開発、展開、保守がはるかに簡単になります。 CakePHP には、最も一般的なタスクの過負荷を軽減するためのライブラリが多数あります。

PHPでHTML/XMLを解析および処理するにはどうすればよいですか? PHPでHTML/XMLを解析および処理するにはどうすればよいですか? Feb 07, 2025 am 11:57 AM

このチュートリアルでは、PHPを使用してXMLドキュメントを効率的に処理する方法を示しています。 XML(拡張可能なマークアップ言語)は、人間の読みやすさとマシン解析の両方に合わせて設計された多用途のテキストベースのマークアップ言語です。一般的にデータストレージに使用されます

See all articles