首先声明:我们要构建的是扩展或者模块名为hello_module.该模块提供一个方法:hello_word.

1、php环境的搭建

我们一般使用源码包编译安装,而不是binary包安装。因为使用PHP的二进制分发包安装有些冒险,这些版本倾向于忽略./configure的两个重要选项,它们在开发过程中很便利:
第一个--enable-debug。这个选项将把附加的符号信息编译进PHP的执行文件,以便如果发生段错误,你能从中得到一个内核转储文件,使用gdb追踪并发现什么地方以及为什么会发生段错误。
另 一个选项依赖于你的PHP版本。在PHP 4.3中该选项名为--enable-experimental-zts,在PHP 5及以后的版本中为--enable-maintainer-zts。这个选项使PHP以为自己执行于多线程环境,并且使你能捕获通常的程序错误,然而它 们在非多线程环境中是无害的,却使你的扩展不可安全用于多线程环境。一旦你已经使用这些额外的选项编译了PHP并安装于你的开发服务器(或者工作站)中,你就可以把你的第一个扩展加入其中了。
   yum install php-devel

Zend 引擎提供了一个内存管理器,有在扩展中跟踪内存泄漏的能力并提供详尽的调试信息。跟踪在默认情况下是被禁用的,同时也是线程安全的。要打开的话,应将 --enable-debug 和 --enable-maintainer-zts 选项与其他常用选项一起传给 configure。要获得从源代码构建 PHP 的说明,请看位于 安装前需要考虑的事项 的说明。

典型的 configure 命令行可能看起来象这样:

$ ./configure --prefix=/usr/local/php --enable-debug --enable-maintainer-zts --enable-cgi --enable-cli --with-mysql=/path/to/mysql

    1)一般可以把php安装在/usr/local/php目录下。
    2)php的二进制可执行文件都在/usr/local/php/bin目录,包括php自带工具phpize.
       phpize实际上是个shell脚本,可以用vi phpize来查看其内容.
注意:使用phpize需要安装autoconf 宏。
因为config.m4 文件使用 GNU autoconf 语法编写。简而言之,就是用强大的宏语言增强的 shell 脚本。注释用字符串 dnl 分隔,字符串则放在左右方括号中间(例如,[ 和 ])。字符串可按需要多次嵌套引用。完整的语法参考可参见位于http://www.gnu.org/software/autoconf/manual/
安装autoconf 宏最简单的方法:apt-get install autoconf

2、ext_skel脚本

PHP 扩展由几个文件组成,这些文件对所有扩展来说都是通用的。不同扩展之间,这些文件的很多细节是相似的,只是要费力去复制每个文件的内容。幸运的是,有脚本可以做所有的初始化工作,名为 ext_skel,自 PHP 4.0 起与其一起分发。

不带参数运行 ext_skel 在 PHP 5.3.2 中会产生以下输出:

  1. <pre name="code" class="plain">php-5.3.2/ext$ ./ext_skel
  2. ./ext_skel --extname=module [--proto=file] [--stubs=file] [--xml[=file]]
  3. [--skel=dir] [--full-xml] [--no-help]
  4. --extname=module   module is the name of your extension
  5. --proto=file       file contains prototypes of functions to create
  6. --stubs=file       generate only function stubs in file
  7. --xml              generate xml documentation to be added to phpdoc-cvs
  8. --skel=dir         path to the skeleton directory
  9. --full-xml         generate xml documentation for a self-contained extension
  10. (not yet implemented)
  11. --no-help          don't try to be nice and create comments in the code
  12. and helper functions to test if the module compiled</pre>

 通常来说,开发一个新扩展时,仅需关注的参数是 --extname 和 --no-help。除非已经熟悉扩展的结构,不要想去使用 --no-help; 指定此参数会造成 ext_skel 不会在生成的文件里省略很多有用的注释。

剩下的 --extname 会将扩展的名称传给 ext_skel。"name" 是一个全为小写字母的标识符,仅包含字母和下划线,在 PHP 发行包的 ext/ 文件夹下是唯一的。

 --proto选项允许开发人员指定一个头文件,由此创建一系列 PHP 函数,表面上看就是要开发基于一个函数库的扩展,但对大多数头现代的文件来说很少能起作用。如果用 zlib.h 头文件来做测试,就会导致在 ext_skel 的输出文件中存在大量的空的和无意义的原型文件。--xml 和 --full-xml 选项当前完全不起作用。--skel 选项可用于指定用一套修改过的框架文件来工作,这是本节范围之外的话题了。

3、扩展组成文件

不管是通过手工,通过

ext_skel ,还是通过另外的扩展生成器,所有的扩展都会有以下个文件:

1)  

config.m4:phpize用来准备构建系统哪些扩展的配置文件configure 选项 ,是UNIX 构建系统配置。对应的win系统是config.w32:             http://www.php.net/manual/zh/internals2.buildsys.configunix.php

2) php_hello_module.h

:包含引用的头文件当将扩展作为静态模块构建并放入PHP 二进制包时,构建系统要求用 php_ 加扩展的名称命名的 头文件包含一个对扩展模块结构的指针定义。就象其他头文件,此文件经常包含附加的宏、原型和全局量。当然你可以把头文件内容放在源文件hello_module.c顶部。分开只是让代码组织更清晰,而且是个很好的习惯。

3) hello_module.c :

包含模块函数的源码文件

扩展应包含任意数量的头文件、源文件、单元测试和其他支持文件,此四个文件仅够组成最小的扩展。hello_module扩展的文件列表如下所示:
  1. ext/
  2. hello_module/
  3. config.m4
  4. config.w32
  5. CREDITS
  6. EXPERIMENTAL
  7. php_hello_module.h
  8. hello_module.c
  9. tests/
  10. 001.phpt

4、与 UNIX 构建系统交互: config.m4

config.m4文件负责在配置时解析configure的命令行选项。这就是说它将检查所需的外部文件并且要做一些类似配置与安装的任务。config.m4 文件告诉 UNIX 构建系统哪些扩展 configure 选项是支持的,你需要哪些扩展库,以及哪些源文件要编译成它的一部分。对所有经常使用的 autoconf 宏,包括 PHP 特定的及 autoconf 内建的,

config.m4 文件举例
  1. dnl $Id$
  2. dnl config.m4 for extension example
  3. PHP_ARG_WITH(example, for example support,
  4. [  --with-example[=FILE]       Include example support. File is the optional path to example-config])
  5. PHP_ARG_ENABLE(example-debug, whether to enable debugging support in example,
  6. [  --enable-example-debug        example: Enable debugging support in example], no, no)
  7. PHP_ARG_WITH(example-extra, for extra libraries for example,
  8. [  --with-example-extra=DIR      example: Location of extra libraries for example], no, no)
  9. dnl 检测扩展是否已启用
  10. if test "$PHP_EXAMPLE" != "no"; then
  11. dnl 检测 example-config。首先尝试所给出的路径,然后在 $PATH 中寻找
  12. AC_MSG_CHECKING([for example-config])
  13. EXAMPLE_CONFIG="example-config"
  14. if test "$PHP_EXAMPLE" != "yes"; then
  15. EXAMPLE_PATH=$PHP_EXAMPLE
  16. else
  17. EXAMPLE_PATH=`$php_shtool path $EXAMPLE_CONFIG`
  18. fi
  19. dnl 如果找到可用的 example-config,就使用它
  20. if test -f "$EXAMPLE_PATH" && test -x "$EXAMPLE_PATH" && $EXAMPLE_PATH --version > /dev/null 2>&1; then
  21. AC_MSG_RESULT([$EXAMPLE_PATH])
  22. EXAMPLE_LIB_NAME=`$EXAMPLE_PATH --libname`
  23. EXAMPLE_INCDIRS=`$EXAMPLE_PATH --incdirs`
  24. EXAMPLE_LIBS=`$EXAMPLE_PATH --libs`
  25. dnl 检测扩展库是否工作正常
  26. PHP_CHECK_LIBRARY($EXAMPLE_LIB_NAME, example_critical_function,
  27. [
  28. dnl 添加所需的 include 目录
  29. PHP_EVAL_INCLINE($EXAMPLE_INCDIRS)
  30. dnl 添加所需的扩展库及扩展库所在目录
  31. PHP_EVAL_LIBLINE($EXAMPLE_LIBS, EXAMPLE_SHARED_LIBADD)
  32. ],[
  33. dnl 跳出
  34. AC_MSG_ERROR([example library not found. Check config.log for more information.])
  35. ],[$EXAMPLE_LIBS]
  36. )
  37. else
  38. dnl 没有可用的 example-config,跳出
  39. AC_MSG_RESULT([not found])
  40. AC_MSG_ERROR([Please check your example installation.])
  41. fi
  42. dnl 检测是否启用调试
  43. if test "$PHP_EXAMPLE_DEBUG" != "no"; then
  44. dnl 是,则设置 C 语言宏指令
  45. AC_DEFINE(USE_EXAMPLE_DEBUG,1,[Include debugging support in example])
  46. fi
  47. dnl 检测额外的支持
  48. if test "$PHP_EXAMPLE_EXTRA" != "no"; then
  49. if test "$PHP_EXAMPLE_EXTRA" == "yes"; then
  50. AC_MSG_ERROR([You must specify a path when using --with-example-extra])
  51. fi
  52. PHP_CHECK_LIBRARY(example-extra, example_critical_extra_function,
  53. [
  54. dnl 添加所需路径
  55. PHP_ADD_INCLUDE($PHP_EXAMPLE_EXTRA/include)
  56. PHP_ADD_LIBRARY_WITH_PATH(example-extra, $PHP_EXAMPLE_EXTRA/lib, EXAMPLE_SHARED_LIBADD)
  57. AC_DEFINE(HAVE_EXAMPLEEXTRALIB,1,[Whether example-extra support is present and requested])
  58. EXAMPLE_SOURCES="$EXAMPLE_SOURCES example_extra.c"
  59. ],[
  60. AC_MSG_ERROR([example-extra lib not found. See config.log for more information.])
  61. ],[-L$PHP_EXAMPLE_EXTRA/lib]
  62. )
  63. fi
  64. dnl 最后,将扩展及其所需文件等信息传给构建系统
  65. PHP_NEW_EXTENSION(example, example.c $EXAMPLE_SOURCES, $ext_shared)
  66. PHP_SUBST(EXAMPLE_SHARED_LIBADD)
  67. fi

注意:凡是带有dnl前缀的都是注释,注释是不被解析的。

4.1 PHP_ARG_*: 赋予用户可选项

 在以上的 

config.m4 例子中,两条注释后,最先见到的 3 行代码,使用了 PHP_ARG_WITH() 和 PHP_ARG_ENABLE()。这些给 configure 提供了可选项,和在运行 ./configure --help 时显示的帮助文本。就象名称所暗示的,其两者的不同点在于是创建 --with-* 选项还是 --enable-* 选项。每个扩展应提供至少一个以上的选项以及扩展名称,以便用户可选择是否将扩展构建至 PHP 中。按惯例,PHP_ARG_WITH() 用于取得参数的选项,例如扩展所需库或程序的位置;而 PHP_ARG_ENABLE() 用于代表简单标志的选项。

不管你使用哪一个指令,你都应该注释掉另外一个。也就是说,如果你使用了–enable-my_module,那就应该去掉–with-my_module。反之亦然。

configue使用例子:./configure   --enable-hello_module
则将
  dnl PHP_ARG_ENABLE(hello_module, whether to enablehello_module support,
  dnl Make sure that the comment is aligned:
  dnl [ --enable-hello_module      Enablehello_module support])
修改成
  PHP_ARG_ENABLE(hello_module, whether to enablehello_module support,
  [ --enable-hello_module      Enablehello_module support])

4.2 处理用户选择

       config.m4

可给用户提供一些做什么的选择,现在就是做出选择的时候了。在上例中,三个选项在未指定时显然默认为 "no"。习惯上,最好用此值作为用于启用扩展的选项的默认值,为了扩展与 PHP 分开构建则用 phpize 覆盖此值,而要构建在 PHP 中时则不应被默认值将扩展空间弄乱。处理这三个选项的代码要复杂得多。

处理 --with-example[=FILE] 选项

首先检测是否设置了 --with-example[=FILE] 选项。如此选项未被指定,或使用否定的格式(--without-example ),或赋值为 "no" 时,它会控制整个扩展的含有物其他任何事情都不会发生。在上面的例子中所指定的值为 /some/library/path/example-config,所以第一个 test 成功了。

接下来,代码调用 AC_MSG_CHECKING(),这是一个 autoconf 宏,输出一行标准的如 "checking for ..." 的信息,并检测用户假定的 example-config 是否是一个明确的路径。在这个例子中,PHP_EXAMPLE 所取到的值为 /some/library/path/example-config,现已复制到 EXAMPLE_PATH 变量中了。只有用户指定了 --with-example ,才会执行代码 $php_shtool path $EXAMPLE_CONFIG,尝试使用用户当前的 PATH 环境变量推测 example-config 的位置。无论如何,下一步都是检测所选的EXAMPLE_PATH 是否是正常文件,是否可执行,及是否执行成功。如成功,则调用 AC_MSG_RESULT(),结束由 AC_MSG_CHECKING() 开始的输出行。否则,调用 AC_MSG_ERROR(),打印所给的信息并立即中断执行 configure。

代码现在执行几次 example-config 以确定一些站点特定的配置信息。下一步调用的是 PHP_CHECK_LIBRARY(),这是 PHP 构建系统提供的一个宏,包装了 autoconf 的 AC_CHECK_LIB() 函数。PHP_CHECK_LIBRARY() 尝试编译、链接和执行程序,在第一个参数指定的库中调用由第二个参数指定的符号,使用第五个参数给出的字符串作为额外的链接选项。如果尝试成功了,则运行第三个参数所给出的脚本。此脚本从 example-config 所提供的原始的选项字符串中取出头文件路径、库文件路径和库名称,告诉 PHP 构建系统。如果尝试失败,脚本则运行第四个参数中的脚本。此时调用 AC_MSG_ERROR() 来中断程序执行。

处理 --enable-example-debug 选项

处理 --enable-example-debug 很简单。只简单地检测其真实值。如果检测成功,则调用 AC_DEFINE() 使 C 语言宏指令 USE_EXAMPLE_DEBUG 可用于扩展的源代码。第三个参数是给 config.h 的注释字符串,通常可放心的留空。

处理 --with-example-extra=DIR 选项

对于此例子来说,由 --with-example-extra=DIR 选项所请求的假定的“额外”功能操作不会与假定的 example-config 程序共享,也没有默认的搜索路径。因此,用户需要在所需的库之前提供设置程序。有点不象现实中的扩展,在这里的设置仅仅起说明性的作用。

代码开始用已熟知的方式来检测 PHP_EXAMPLE_EXTRA 的真实值。如果所提供的为否定形式,则不会进行其他处理,用户也不会请求额外的功能。如果所提供的为未提供参数的肯定形式,则调用 AC_MSG_ERROR() 中止处理。下一步则再次调用PHP_CHECK_LIBRARY()。这一次,因为没有提供预定义编译选项,PHP_ADD_INCLUDE() 和 PHP_ADD_LIBRARY_WITH_PATH() 用于构建额外功能所需的头文件路径、库文件路径和库标志。也调用 AC_DEFINE() 来指示所请求的额外功能代码是可用的,设置变量来告诉以后的代码,有额外的源代码要构建。如果检测失败,则调用所熟悉的 AC_MSG_ERROR()。另一种不同的处理失败的方式是更换为调用 AC_MSG_WARNING(),例如:

4.3 PHP_NEW_EXTENSION宏

默认情况下,通过ext_skel创建的config.m4都能接受指令,并且会自动启用该扩展。启用该扩展是通过PHP_EXTENSION这个宏进行 的。如果你要改变一下默认的情况,想让用户明确的使用 –enable-my_module或 –with-my_module指令来把扩展包含在PHP二进制文件当中,那么将 “if test "$PHP_MY_MODULE" != "no"”改为“if test "$PHP_MY_MODULE" == "yes"”即可。

if test "$PHP_MY_MODULE" == "yes"; thendnl

PHP_EXTENSION(hello_module, $ext_shared)

fi

这样就会导致在每次重新配置和编译PHP时都要求用户使用 –enable-my_module指令。

PHP_NEW_EXTENSION()

就是宏告诉构建系统去构建扩展本身和被其用到的文件。

PHP_NEW_EXTENSION()参数:

第一个参数是扩展的名称,和包含它的目录同名。

     第二个参数是做为扩展的一部分的所有源文件的列表

。参见 PHP_ADD_BUILD_DIR() 以获取将在子目录中源文件添加到构建过程的相关信息。

第三个参数总是 $ext_shared, 当为了 --with-example[=FILE] 而调用 PHP_ARG_WITH()时,由 configure 决定参数的值。

第四个参数指定一个“SAPI 类”,仅用于专门需要 CGI 或 CLI SAPI 的扩展。其他情况下应留空。

第五个参数指定了构建时要加入 CFLAGS 的标志列表。

第六个参数是一个布尔值,为 "yes" 时会强迫整个扩展使用 $CXX 代替 $CC 来构建。第三个以后的所有参数都是可选的。最后,调用 PHP_SUBST() 来启用扩展的共享构建。

  例如我们要构建扩展是hello_module
  1. dnl $Id$
  2. dnl config.m4 for extension hello
  3. PHP_ARG_ENABLE(hello, whether to enable hello support,
  4. [  --enable-hello           Enable hello support])
  5. if test "$PHP_HELLO" != "no"; then
  6. PHP_NEW_EXTENSION(hello_module, hello_module.c, $ext_shared)
  7. fi

5、扩展模块代码的

6、创建扩展的详细步骤

我们创建扩展最好放在php的源码包的ext目录下。如/opt/php-5.3.2/ext/下
1) ext_skel来建立一个php扩展的一个框架
root@ubuntu:/# cd /opt/php-5.3.2/ext/
root@ubuntu:opt/php-5.3.2/ext/]# ./ext_skel --extname=hello_module
执行了这个步骤以后看到这样的结果: 
  1. Creating directory hello_module
  2. Creating basic files: config.m4 config.w32 .cvsignore hello_module.c php_hello_module.h CREDITS EXPERIMENTAL tests/001.phpt hello_module.php [done].
  3. To use your new extension, you will have to execute the following steps:
  4. 1.  $ cd ..
  5. 2.  $ vi ext/hello_module/config.m4
  6. 3.  $ ./buildconf
  7. 4.  $ ./configure --[with|enable]-hello_module
  8. 5.  $ make
  9. 6.  $ ./php -f ext/hello_module/hello_module.php
  10. 7.  $ vi ext/hello_module/hello_module.c
  11. 8.  $ make
  12. Repeat steps 3-6 until you are satisfied with ext/hello_module/config.m4 and
  13. step 6 confirms that your module is compiled into PHP. Then, start writing
  14. code and repeat the last two steps as often as necessary.
在这个目录下生成一个目录叫hello_module
进入这里面我们看看
root@ubuntu:opt/php-5.3.2/ext# #cd hello_module

root@ubuntu:/opt/php-5.3.2/ext/hello_module# ls

config.m4  config.w32  CREDITS  EXPERIMENTAL  hello_module.c  hello_module.php  php_hello_module.h  tests

然后我们要修改文件顺序是
configue.m4
hello_module.c
php_hello_module.h
2)编辑config.m4文件,我们使用enable-hello_module选项:
dnl PHP_ARG_ENABLE(hello_module, whether to enablehello_module support,
dnl Make sure that the comment is aligned:
dnl [ --enable-hello_module      Enable hello_module support])
修改成

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

3)vi hello_module.c
主要是给模块添加函数:
 /* Every user visible function must have an entry in my_module_functions[].*/
function_entry hello_module_functions[] = {
    PHP_FE(hello_world,    NULL) /* 添加着一行代码 */
    PHP_FE(confirm_my_module_compiled,   NULL) /* For testing, remove later. */
    {NULL, NULL, NULL}   /* Must be the last line in my_module_functions[] */
};
在文件的最后添加下列代码
 定义函数:
PHP_FUNCTION(hello_world)
{
    zend_printf("hello sdomain!");
}
4)修改php_hello_module.h
在PHP_FUNCTION(confirm_my_module_compiled ); /* For testing, remove later. */ 这行的下面添加一行:
PHP_FUNCTION(hello_world); /* 函数的声明 */
5) 执行phpiz并编译
 root@ubuntu:/opt/php-5.3.2/ext/hello_module# /usr/local/php/bin/phpize
 执行以后会看到下面的

Configuring for:
         PHP Api Version:         20090626
         Zend Module Api No:      20090626
         Zend Extension Api No:   220090626

然后执行:
root@ubuntu:/opt/php-5.3.2/ext/hello_module#./configure  --enable-hello_module --with-php-config=/usr/local/php/bin/php-config
root@ubuntu:/opt/php-5.3.2/ext/hello_module# make
这个时候会在当前的目录下生成一个目录叫modules先存放着hello_module.so文件
cp modules/hello_module.so     /usr/local/php/ext/
然后再把hello_module.so文件拷到php.ini里面的extension_dir所指定的位置
6)开启扩展
php.ini文件中打开这个扩展
extension=hello_module.so
重新起动apache
用phpinfo来察看一下ok了

转载于:https://blog.51cto.com/zhaojunjie/1028541

php kuozhan相关推荐

  1. python装饰器由浅入深_由浅入深,走进Python装饰器-----第五篇:进阶--类装饰类

    **类装饰器** @类 类 4.1 用类装饰器来扩展原函数( 增加属性和方法 ) # 用类装饰器来扩展原函数, 通过对象函数化触发__call__方法,进行返回 class KuoZhan(): de ...

  2. java linux urlencode_iOS urlEncode编码解码(非过时方法,已解决)

    ios urlEncode解决字符串数据以url的形式传递给web服务器时,字符串中是不允许出现空格和特殊字符的,因此通常需要用到urlEncode技术来对url进行简单的编码,以便更好的传输给服务器 ...

  3. python中文编码-彻底弄懂python编码

    在编写python程序的过程中,中英文混用经常会出现编码问题.围绕此问题,本文首先介绍编码的含义及常用编码,随后列举几个python经常遇到的编码异常及解决方法,接着列举笔者在实践中遇到的异常出现的情 ...

  4. 由浅入深,走进Python装饰器-----第五篇:进阶--类装饰类

    上一篇:由浅入深,走进Python装饰器-----第四篇:进阶--函数装饰类 类装饰器 @类 类 4.1 用类装饰器来扩展原类( 增加属性和方法 ) # 用类装饰器来扩展原函数, 通过对象函数化触发_ ...

  5. java全面的知识体系结构总结

    Java知识体系 目的:为了更好的认识java体系 1.java基础知识 1.1 基础知识 1.1.1 配置环境变量 新建java_home变量(安装目录),值为:C:\Program Files\J ...

  6. C++的inline函数

    C++中使用const 变量替换宏定义 当然C++中也有使用inline 函数替换宏代码片段: #include <iostream>using namespace std;inline ...

  7. 迷宫问题 POJ - 3984

    题目 定义一个二维数组: int maze[5][5] = {0, 1, 0, 0, 0,0, 1, 0, 1, 0,0, 0, 0, 0, 0,0, 1, 1, 1, 0,0, 0, 0, 1, 0 ...

  8. jQuery中的几个模块总结

    Query插件,以备并希望在前端方面有所长进.请批评指正. 一,类型判断全解 JQuery判断类型扩展方法:$.type() 1 /*type: function( obj ) {2 if ( obj ...

  9. 获取所有某格式文件到文件

    '扫描文件 sub scan(folder_) Set fso=createobject("scripting.filesystemobject") set folder_=fso ...

最新文章

  1. python语言使用什么语句实现上下文管理协议_Python 技巧探究:上下文管理器和with语句...
  2. 在SpringMVC中使用Jackson并格式化时间
  3. boost::reverse_graph用法的测试程序
  4. WPF学习笔记 - 不一样的皇帝的新衣
  5. java 几个线程池的理解
  6. ADBPGGreenplum成本优化之磁盘水位管理
  7. 无忧PHP企业网站内容管理系统源码v2.8 标准版
  8. sf | 读取和保存空间矢量数据
  9. 解决Spring Boot集成Shiro,配置类使用Autowired无法注入Bean问题
  10. 论文|SDNE的算法原理、代码实现和在阿里凑单场景中的应用说明(附代码)
  11. HTML5 file对象和blob对象的互相转换
  12. 几个比较好的app开发框架
  13. Packet Tracer 思科模拟器入门教程 之十 路由器单臂路由配置
  14. 主表先查出数据再左连接
  15. 配音软件哪个好用?这几个软件值得你试一试
  16. 万维网Web自动搜索引擎(技术报告)
  17. 噩梦射手(SurvivalShooter)教程(八)
  18. android仿微信发状态图片上传
  19. 如何阅读一个前向推理框架?以NCNN为例。
  20. Python分类算法——多标签图像分类

热门文章

  1. C++中bool类型变量初值对程序的影响
  2. Asp.Net 之 通过调用 WScript.Shell 启动本地 exe 程序时产生“ automation服务器不能创建对象 ”的错误...
  3. 微软职位内部推荐-Senior Software Engineer_Azure
  4. 使用StarWind为RAC设置存储
  5. QT自定义窗口插件在QT Creator的应用
  6. shiro学习总结(一)----初识shiro
  7. [Swift]LeetCode496. 下一个更大元素 I | Next Greater Element I
  8. VIM - 每行前或者每行后增加相同的字符串
  9. java.lang.NoSuchMethodError: org.springframework.beans.factory.annotation.InjectionMetadata.init(L
  10. asp.net各种类型视频播放代码(全)(转)