如何开始用 C 语言编写 PHP5 扩展

发布于 2024-07-12 02:09:27 字数 2508 浏览 8 评论 0原文

我正在编写一个 PHP5 扩展,虽然我可以用 C 语言编写它,但使用 C++ 并利用 STL 和 Boost 会更容易。

问题是,我见过的教程只涉及C,而我'我正在寻找一个使用 C++ 的基本示例,

这是我迄今为止尝试过的:

config.m4

[ --enable-hello   Enable Hello World support])

if test "$PHP_HELLO" = "yes"; then
  AC_DEFINE(HAVE_HELLO, 1, [Whether you have Hello World])
  PHP_NEW_EXTENSION(hello, hello.cpp, $ext_shared)
fi

php_hello.h

请注意,我尝试将 PHP 接口的位声明为 extern "C"

#ifndef PHP_HELLO_H
#define PHP_HELLO_H 1


extern "C" {

#define PHP_HELLO_WORLD_VERSION "1.0"
#define PHP_HELLO_WORLD_EXTNAME "hello"

PHP_FUNCTION(hello_world);

extern zend_module_entry hello_module_entry;
#define phpext_hello_ptr &hello_module_entry

}
#endif

hello.cpp

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"
#include "php_hello.h"

static function_entry hello_functions[] = {
    PHP_FE(hello_world, NULL)

    {NULL, NULL, NULL}
};

zend_module_entry hello_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
    STANDARD_MODULE_HEADER,
#endif
    PHP_HELLO_WORLD_EXTNAME,
    hello_functions,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
#if ZEND_MODULE_API_NO >= 20010901
    PHP_HELLO_WORLD_VERSION,
#endif
    STANDARD_MODULE_PROPERTIES
};

#ifdef COMPILE_DL_HELLO
ZEND_GET_MODULE(hello)
#endif

PHP_FUNCTION(hello_world)
{
    RETURN_STRING("Hello World", 1);
}

....这里是我的构建错误:

如果我 phpize、配置并制作它,我会得到以下内容(为了清晰起见,重新格式化)

$ make
/bin/bash /home/paul/php5/php-5.2.8/ext/hello2/libtool 
   --mode=compile  
   -I. 
   -I/home/paul/php5/php-5.2.8/ext/hello2 -DPHP_ATOM_INC 
   -I/home/paul/php5/php-5.2.8/ext/hello2/include 
   -I/home/paul/php5/php-5.2.8/ext/hello2/main 
   -I/home/paul/php5/php-5.2.8/ext/hello2 
   -I/usr/local/include/php 
   -I/usr/local/include/php/main 
   -I/usr/local/include/php/TSRM 
   -I/usr/local/include/php/Zend 
   -I/usr/local/include/php/ext 
   -I/usr/local/include/php/ext/date/lib  
   -DHAVE_CONFIG_H     
   -c /home/paul/php5/php-5.2.8/ext/hello2/hello.cpp 
   -o hello.lo 
libtool: compile: unrecognized option `-I.'
libtool: compile: Try `libtool --help' for more information.
make: *** [hello.lo] Error 1

我怀疑我需要对 config.m4 做更多工作才能创建一个工作 makefile,但我对 GCC 还很陌生工具链。

如果有帮助的话,我只针对 php 5.2.6+,并且只在 Linux 上(特别是 Ubuntu 8.04)。 我的编译环境使用的是Ubuntu 8.10,使用的是gcc 4.3.2

指点感激不尽!

I'm writing a PHP5 extension, and while I could write it in C, it would be easier to use C++ and take advantage of the STL and Boost.

Trouble is, the tutorials I've seen only deal with C, and I'm looking for a basic example which uses C++

Here's what I've tried so far:

config.m4

[ --enable-hello   Enable Hello World support])

if test "$PHP_HELLO" = "yes"; then
  AC_DEFINE(HAVE_HELLO, 1, [Whether you have Hello World])
  PHP_NEW_EXTENSION(hello, hello.cpp, $ext_shared)
fi

php_hello.h

Note my attempt to declare the bits that PHP interfaces with as extern "C"

#ifndef PHP_HELLO_H
#define PHP_HELLO_H 1


extern "C" {

#define PHP_HELLO_WORLD_VERSION "1.0"
#define PHP_HELLO_WORLD_EXTNAME "hello"

PHP_FUNCTION(hello_world);

extern zend_module_entry hello_module_entry;
#define phpext_hello_ptr &hello_module_entry

}
#endif

hello.cpp

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"
#include "php_hello.h"

static function_entry hello_functions[] = {
    PHP_FE(hello_world, NULL)

    {NULL, NULL, NULL}
};

zend_module_entry hello_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
    STANDARD_MODULE_HEADER,
#endif
    PHP_HELLO_WORLD_EXTNAME,
    hello_functions,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
#if ZEND_MODULE_API_NO >= 20010901
    PHP_HELLO_WORLD_VERSION,
#endif
    STANDARD_MODULE_PROPERTIES
};

#ifdef COMPILE_DL_HELLO
ZEND_GET_MODULE(hello)
#endif

PHP_FUNCTION(hello_world)
{
    RETURN_STRING("Hello World", 1);
}

....and here are my build errors:

If I phpize, configure and make this, I get the following (reformatted for clarity)

$ make
/bin/bash /home/paul/php5/php-5.2.8/ext/hello2/libtool 
   --mode=compile  
   -I. 
   -I/home/paul/php5/php-5.2.8/ext/hello2 -DPHP_ATOM_INC 
   -I/home/paul/php5/php-5.2.8/ext/hello2/include 
   -I/home/paul/php5/php-5.2.8/ext/hello2/main 
   -I/home/paul/php5/php-5.2.8/ext/hello2 
   -I/usr/local/include/php 
   -I/usr/local/include/php/main 
   -I/usr/local/include/php/TSRM 
   -I/usr/local/include/php/Zend 
   -I/usr/local/include/php/ext 
   -I/usr/local/include/php/ext/date/lib  
   -DHAVE_CONFIG_H     
   -c /home/paul/php5/php-5.2.8/ext/hello2/hello.cpp 
   -o hello.lo 
libtool: compile: unrecognized option `-I.'
libtool: compile: Try `libtool --help' for more information.
make: *** [hello.lo] Error 1

I suspect I need more work doing to the config.m4 in order to create a working makefile but I'm pretty new to the GCC toolchain.

If it helps, I'm only targetting php 5.2.6+, and only on Linux (specifically, Ubuntu 8.04). My build environment is using Ubuntu 8.10, using gcc 4.3.2

Pointers gratefully received!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

很糊涂小朋友 2024-07-19 02:09:27

发布后,我发现 CodeGen_PECL 它根据基于 XML 的扩展描述创建了一个框架扩展。 这包括一个标记使其输出 C++

除了确保头文件使用 extern“C”之外,生成的 cpp 文件还确保 ZEND_GET_MODULE(hello) 也位于 extern“C”块内。

正如预期的那样,最大的区别在于 m4 文件,它看起来像这样:

dnl
dnl $ Id: $
dnl

PHP_ARG_ENABLE(hello, whether to enable hello functions,
[  --enable-hello         Enable hello support])

if test "$PHP_HELLO" != "no"; then
  PHP_REQUIRE_CXX
  AC_LANG_CPLUSPLUS
  PHP_ADD_LIBRARY(stdc++,,HELLO_SHARED_LIBADD)
  export OLD_CPPFLAGS="$CPPFLAGS"
  export CPPFLAGS="$CPPFLAGS $INCLUDES -DHAVE_HELLO"

  AC_MSG_CHECKING(PHP version)
  AC_TRY_COMPILE([#include <php_version.h>], [
#if PHP_VERSION_ID < 40000
#error  this extension requires at least PHP version 4.0.0
#endif
],
[AC_MSG_RESULT(ok)],
[AC_MSG_ERROR([need at least PHP 4.0.0])])

  export CPPFLAGS="$OLD_CPPFLAGS"


  PHP_SUBST(HELLO_SHARED_LIBADD)
  AC_DEFINE(HAVE_HELLO, 1, [ ])

  PHP_NEW_EXTENSION(hello, hello.cpp , $ext_shared)

fi

因此,如果您遇到同样的问题,请使用 CodeGen_PECL,或改编上面的 m4 示例(并确保您在标头中和 ZEND_GET_MODULE 宏周围使用了 extern "C")

After posting I came across CodeGen_PECL which creates a skeleton extension from an XML based description of the extension. This includes a tag make it output C++

As well as making sure the header file used extern "C", the generated cpp file also ensured the ZEND_GET_MODULE(hello) was inside an extern "C" block also.

As expected, the biggest difference was in the m4 file, which looked like this:

dnl
dnl $ Id: $
dnl

PHP_ARG_ENABLE(hello, whether to enable hello functions,
[  --enable-hello         Enable hello support])

if test "$PHP_HELLO" != "no"; then
  PHP_REQUIRE_CXX
  AC_LANG_CPLUSPLUS
  PHP_ADD_LIBRARY(stdc++,,HELLO_SHARED_LIBADD)
  export OLD_CPPFLAGS="$CPPFLAGS"
  export CPPFLAGS="$CPPFLAGS $INCLUDES -DHAVE_HELLO"

  AC_MSG_CHECKING(PHP version)
  AC_TRY_COMPILE([#include <php_version.h>], [
#if PHP_VERSION_ID < 40000
#error  this extension requires at least PHP version 4.0.0
#endif
],
[AC_MSG_RESULT(ok)],
[AC_MSG_ERROR([need at least PHP 4.0.0])])

  export CPPFLAGS="$OLD_CPPFLAGS"


  PHP_SUBST(HELLO_SHARED_LIBADD)
  AC_DEFINE(HAVE_HELLO, 1, [ ])

  PHP_NEW_EXTENSION(hello, hello.cpp , $ext_shared)

fi

So, if you're struggling with the same problem, use CodeGen_PECL, or adapt the m4 sample above (as well as making sure you've used extern "C" in your header and around the ZEND_GET_MODULE macro)

且行且努力 2024-07-19 02:09:27

这里还有包装类(并以 Class::Method 样式导出函数)的快速介绍:http:// /devzone.zend.com/article/4486

对我来说,最有用的部分是为 phpize 添加 C++ 编译器/链接规则到 config.m4 的行。

There's also this quickie intro to wrapping a class (and exporting functions in Class::Method style) here: http://devzone.zend.com/article/4486

For me the most useful part is the lines to add for C++ compiler/linking rules to config.m4 for phpize.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文