乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Python擴(kuò)展方法及工具比較 歪歪蟲

       ekylin 2006-08-10
      Python擴(kuò)展方法及工具比較

      一、普通擴(kuò)展方法
        擴(kuò)展Python包括三個(gè)步驟:
      1. 創(chuàng)建源程序(C, C++, java, ...);
      2. 為源程序?qū)憌rap代碼;
        包括四個(gè)步驟:
      Ø   include "Python.h";
      Ø   為每個(gè)模塊函數(shù)寫wrap,即:PyObject* Module_func();
      Ø   為每個(gè)模塊函數(shù)寫函數(shù)定義,即:PyMethodDef ModuleMethods[]對(duì)應(yīng)表;
      Ø   寫模塊的初始化函數(shù):void initModule()部分。
      3. 編譯連接;
        有兩種方法:
      (1)使用distutils包。步驟如下:
      Ø   修改distutils包中的setup.py文件;
      Ø   根據(jù)需要運(yùn)行$ python setup.py build或$ python setup.py install命令,生成擴(kuò)展模塊的共享庫文件。
      (2)直接使用gcc命令將模塊編譯成共享庫。命令如下:
      $ gcc -fpic -c -I/usr/include/python2.2 -I/usr/lib/python2.2/config foo.c wrap_foo.c
      $ gcc -shared -o foo.so foo.o wrap_foo.o
        這樣便生成了python可用的foo模塊。
      4. 使用擴(kuò)展內(nèi)容
        進(jìn)入python環(huán)境,通過import foo,使用foo模塊中的函數(shù)。如用foo.func()調(diào)用foo模塊中的func()函數(shù)。

      二、Python的C++擴(kuò)展
        通過C++擴(kuò)展python也是可以的,只不過有一些限制。如果主函數(shù)(Python解釋器)被C編譯器編譯和連接,那么構(gòu)造器中不能使用全局和靜態(tài)對(duì)象。但如果使用C++編譯器則沒有這個(gè)問題。另外,將被Python解釋器調(diào)用的函數(shù)(特別是初始化函數(shù)),需要在函數(shù)體外使用extern "C" 聲明。同時(shí)要在Python頭文件處使用extern "C" {...}聲明。
        一個(gè)示例程序(wraper文件):
      extern "C"
      {
      #include "Python.h"
      }
      PyObject *cppextest_print_logo(PyObject *self, PyObject *args)
      {
          char *string;
          if (!PyArg_ParseTuple(args, "s", &string))   return NULL;
          return Py_None;
      }
      static PyMethodDef
      cppextestMethods[] = {
          {"print_logo", cppextest_print_logo, METH_VARARGS},
          {NULL, NULL},
      };
      extern "C"
      void initcppextest(void)
      {
          Py_InitModule("cppextest", cppextestMethods);
      }


      三、使用工具進(jìn)行擴(kuò)展
        雖然擴(kuò)展過程并不復(fù)雜,但也可以使用許多已知的工具簡(jiǎn)化擴(kuò)展過程。
      (1) SWIG
        由David Beazley創(chuàng)建,是一個(gè)自動(dòng)的擴(kuò)展構(gòu)造工具。它讀入注釋的C/C++頭文件,為python、tcl、perl等多種腳本語言產(chǎn)生wrap代碼。SWIG可以包裝大量C++特性到Python的擴(kuò)展模塊中。詳情可參考http://www.
        評(píng)價(jià):swig簡(jiǎn)單,可以支持多種腳本文件,但支持的c++特性不完備。

      (2) SIP
        由Phil Thompson創(chuàng)建,是一個(gè)C++模塊構(gòu)造器,專門為C++的類創(chuàng)造wrapper。它曾經(jīng)被用于創(chuàng)建PyQt和PyKDE擴(kuò)展模塊,因此比較出名。詳情可參考http://www./sip/。
        評(píng)價(jià):支持C++特征很齊全,但比較復(fù)雜。

      (3) bgen
        該工具被包含在標(biāo)準(zhǔn)Python發(fā)布包中的模塊構(gòu)建工具集里,由Jack Jansen維護(hù)。它用于產(chǎn)生在Macintosh版本可用的Python擴(kuò)展模塊。

      (4) pyfort
        由Paul dubois創(chuàng)建,用來產(chǎn)生Fortran語言生成的擴(kuò)展模塊。詳見http://pyfortran.。

      (5) cxx
        也由Paul Dubois創(chuàng)建,是一個(gè)庫,為Python的C++擴(kuò)展提供了友好的API。Cxx允許將許多python對(duì)象(如list和tuple)使用到STL的運(yùn)算中。庫也提供了C++異常處理到python異常處理的轉(zhuǎn)化。詳見http://cxx.。

      (6) WrapPy
        由Greg Couch創(chuàng)建,通過讀入C++頭文件來產(chǎn)生擴(kuò)展模塊。詳見http://www.cgl./home/gregc/wrappy/index.html

      (7) Boost Python Library
        由David Abrahams創(chuàng)建。該庫提供了更多與眾不同的C++ wrap到python擴(kuò)展中,而只需要對(duì)要擴(kuò)展的C++類寫很少的附加信息。詳見http://www./libs/python/doc
        評(píng)價(jià):Boost為C++提供了許多實(shí)用的庫,如Regex(正則表達(dá)式庫)、Graph(圖組件和算法)、concept check(檢查泛型編程中的concept)、Thread(可移植的C++多線程庫)、Python(把C++類和函數(shù)映射到Python之中)、Pool(內(nèi)存池管理)等等。
        Boost總體來說是實(shí)用價(jià)值很高,質(zhì)量很高的庫。并且強(qiáng)調(diào)對(duì)跨平臺(tái)的支持。但是Boost中也有很多是實(shí)驗(yàn)性質(zhì)的東西,在實(shí)際的開發(fā)中實(shí)用需要謹(jǐn)慎。
        boost.python支持的c++特性較多,但是比較復(fù)雜。


      四、擴(kuò)展工具的使用
      1. SWIG
        SWIG可以完成多種腳本語言的C/C++擴(kuò)展,包括python、tcl、perl、CHICKEN、php、XML等等許多。它通過構(gòu)造接口函數(shù)和代理類來實(shí)現(xiàn)模擬。
      1) 原理
      (1) 接口函數(shù)
        實(shí)現(xiàn)一系列接口函數(shù)來隱藏一個(gè)結(jié)構(gòu)體的底層實(shí)現(xiàn)。例如對(duì)結(jié)構(gòu)體:
      struct Vector {
          Vector();
          ~Vector();
          double x,y,z;
      };
      將被轉(zhuǎn)換為以下的函數(shù)集合:
      Vector *new_Vector();
      void delete_Vector(Vector *v);
      double Vector_x_get(Vector *v);
      double Vector_y_get(Vector *v);
      double Vector_y_get(Vector *v);
      void Vector_x_set(Vector *v, double x);
      void Vector_y_set(Vector *v, double y);
      void Vector_z_set(Vector *v, double z);

        于是,這些函數(shù)在解釋器中便可以如下使用:
      % set v [new_Vector]
      % Vector_x_set $v 3.5
      % Vector_y_get $v
      % delete_Vector $v
      % ...

      (2) 代理類
        也叫做shadow類,是真實(shí)C++類的代理。使用代理類時(shí),實(shí)際工作的有兩個(gè)對(duì)象——一個(gè)在腳本語言中,另一個(gè)是C/C++的底層對(duì)象。操作同時(shí)影響著兩個(gè)對(duì)象,但用戶看起來只是一個(gè)。例如,如果你有如下C++定義:
      class Vector {
      public:
      Vector();
      ~Vector();
      double x,y,z;
      };
        使用了代理類機(jī)制后,將會(huì)用很透明的方式訪問結(jié)構(gòu)。例如在Python中,可直接如下訪問:
      >>> v = Vector()
      >>> v.x = 3
      >>> v.y = 4
      >>> v.z = -13
      >>> ...
      >>> del v

      2)支持特性與局限
        SWIG當(dāng)前支持以下的C++特性:
      Ø   類
      Ø   類的構(gòu)造和析構(gòu)
      Ø   虛函數(shù)
      Ø   公共繼承(包括多重繼承)
      Ø   靜態(tài)函數(shù)
      Ø   函數(shù)和方法重載
      Ø   大多數(shù)標(biāo)準(zhǔn)運(yùn)算符的重載
      Ø   引用
      Ø   模板
      Ø   函數(shù)指針
      Ø   名字空間
        雖然SWIG能夠解析大多數(shù)C/C++聲明,但不能提供完備的解析機(jī)制。限制包括一些非常復(fù)雜類型的聲明和C++的高級(jí)特性。下面是目前不被支持的一些特性:
      Ø   一些非常規(guī)的類型聲明。例如,SWIG不支持以下一些聲明:
      /* Non-conventional placement of storage specifier (extern) */
      const int extern Number;
      /* Extra declarator grouping */
      Matrix (foo);   // A global variable
      /* Extra declarator grouping in parameters */
      void bar(Spam (Grok)(Doh));
      Ø   直接在C++源碼運(yùn)行SWIG會(huì)有一些問題。雖然SWIG能夠解析C++類聲明,但是當(dāng)它遇到本身不支持的聲明時(shí),會(huì)自動(dòng)跳過。
      Ø   某些C++的高級(jí)特性目前不被支持。如:
      Ø   友元
      Ø   私有和保護(hù)成員
      Ø   某些操作符的重載(如new、delete等)

      3) 使用方法
        使用SWIG工具來進(jìn)行Python的C++擴(kuò)展,包括以下幾個(gè)步驟:
      Ø   編寫C++源代碼;
      Ø   編寫后綴為.i或者.swg的腳本文件,標(biāo)記頭文件和要擴(kuò)展的類;
      Ø   編譯連接生成共享庫;
      Ø   使用擴(kuò)展。

      (1) 運(yùn)行SWIG
        安裝SWIG成功后,使用以下格式的命令運(yùn)行:
      $ swig [ options ] filename
        選項(xiàng)包括:
      -chicken         Generate CHICKEN wrappers
      -csharp           Generate C# wrappers
      -guile           Generate Guile wrappers
      -java           Generate Java wrappers
      -mzscheme         Generate Mzscheme wrappers
      -ocaml           Generate Ocaml wrappers
      -perl           Generate Perl wrappers
      -php             Generate PHP wrappers
      -pike           Generate Pike wrappers
      -python           Generate Python wrappers
      -ruby           Generate Ruby wrappers
      -sexp           Generate Lisp S-Expressions wrappers
      -tcl             Generate Tcl wrappers
      -xml             Generate XML wrappers
      -c++             Enable C++ parsing
      -Dsymbol         Define a preprocessor symbol
      -Fstandard         Display error/warning messages in commonly used format
      -Fmicrosoft       Display error/warning messages in Microsoft format
      -help           Display all options
      -Idir           Add a directory to the file include path
      -lfile           Include a SWIG library file.
      -module name       Set the name of the SWIG module
      -o outfile         Name of output file
      -outdir dir       Set language specific files output directory
      -swiglib         Show location of SWIG library
      -version         Show SWIG version number
        這只是命令行選項(xiàng)的一個(gè)子集。對(duì)每種目標(biāo)語言都有各自附加的選項(xiàng)??梢允褂妹?swig -help or swig -lang -help"查看全部。

        filename是用戶編寫的SWIG標(biāo)記腳本文件。

      (2) SWIG的輸入
        輸入為編寫的腳本文件,通常后綴為.i或.swg。
        通常該腳本文件的格式如下:
      %module mymodule
      %{
      #include "myheader.h"
      %}
      // Now list ANSI C/C++ declarations
      int foo;
      int bar(int x);
      ...
        模塊名使用"%module"(或-module命令行選項(xiàng))進(jìn)行標(biāo)記。這個(gè)標(biāo)記必須在文件的開始出現(xiàn),用于命名目標(biāo)擴(kuò)展模塊。如果選擇在命令行提供,則不需要"%module"標(biāo)記。
        在"%{ ... %}"中進(jìn)行頭文件和其它特殊的聲明(如% rename、% ignore等)。它將被逐字的復(fù)制到SWIG創(chuàng)建的wrapper文件中。

      (3) SWIG的輸出
        SWIG的輸出是一系列wrapper文件,也可能根據(jù)目標(biāo)文件的不同產(chǎn)生一些其它的文件。默認(rèn)情況下,輸入名為file.i的文件將輸出文件file_wrap.c或file_wrap.cxx(依賴于是否使用了-c++選項(xiàng))。編譯器通常是通過文件后綴來確定源語言(C、C++等)類型的。輸出文件的名字可以通過-o選項(xiàng)修改。例如:
      $ swig -c++ -python -o example_wrap.cpp example.i
        SWIG創(chuàng)建的wrapper文件可直接用來編譯連接產(chǎn)生共享庫,不需要再對(duì)生成文件進(jìn)行編輯。


      2. SIP(A Tool for Generating Python Bindings for C and C++ Libraries)
        Python-SIP是一個(gè)用于為Python生成C++接口的工具。它類似于SWIG,但使用了一個(gè)不同的接口格式。它用于建造PyQt 和PyKDE,支持Qtsignal/slot機(jī)制。
        SIP是一個(gè)為C/C++庫自動(dòng)生成Python綁定的工具。SIP最初于1998年為了PyQt(Python綁定到Qt GUI工具集)而開發(fā)的,但也適合于生成C/C++庫的綁定。
        SIP的命名是因?yàn)樗畛跏亲鳛橐粋€(gè)小的SWIG出現(xiàn)的。與SWIG不同,SIP實(shí)現(xiàn)是為了盡可能最小化的實(shí)現(xiàn)Python與C/C++的整合。

      1)支持特性與局限
        SIP的主要優(yōu)點(diǎn)是綁定加載速度快,內(nèi)存消耗小,尤其在只使用一個(gè)大庫中的小集合時(shí)。它支持的特性主要包括:
      Ø   提供標(biāo)準(zhǔn)Python和C/C++數(shù)據(jù)類型間的自動(dòng)轉(zhuǎn)換;
      Ø   根據(jù)不同參數(shù)重載函數(shù);
      Ø   提供對(duì)C++類保護(hù)方法的接口;
      Ø   可以在Python中定義C++類的子類,包括C++的抽象類;
      Ø   支持原始的C++函數(shù)、類方法、靜態(tài)類方法、虛類方法和抽象類方法;
      Ø   可以在Python中重新實(shí)現(xiàn)C++虛方法和抽象方法;
      Ø   支持全局變量和類變量;
      Ø   支持C++的名字空間;
      Ø   支持C++異常,并能將之轉(zhuǎn)換為Python異常;
      Ø   可以定義C++類和類似的Python數(shù)據(jù)類型之間的映射,并能自動(dòng)調(diào)用;
      Ø   可以在某特定文件中包括可提取文檔;
      Ø   可以在特定文件中包括版權(quán)信息,使其自動(dòng)包含到生成的所有源代碼中;
      Ø   擴(kuò)展過程與特定平臺(tái)無關(guān);
      Ø   SIP也能理解Qt實(shí)現(xiàn)的signal/slot類型安全回調(diào)機(jī)制。

      3) 使用方法
      (1) 使用步驟:
      Ø   寫.sip規(guī)范文件;
      Ø   用命令$ sip -c . foo.sip在當(dāng)前目錄產(chǎn)生C++代碼;
      Ø   寫configure.py腳本文件,用命令$ python configure.py來生成Makefile文件;
      Ø   運(yùn)行$ make;make install完成編譯和安裝擴(kuò)展模塊。

      (2) 運(yùn)行:
        SIP命令行語法如下:
      $ sip [options] [specification]
        其中,specification是模塊規(guī)范文件(通常后綴為sip)的文件名。若被省略則默認(rèn)為stdin。
        命令行選項(xiàng)如下:
      -h
      Display a help message.

      -V
      Display the SIP version number.

      -a file
      The name of the Scintilla API file to generate. This file contains a description of the module API in a form that the Scintilla editor component can use for auto-completion and call tips. By default the file is not generated.

      -b file
      The name of the build file to generate. This file contains the information about the module needed by the SIP build system to generate a platform and compiler specific Makefile for the module. By default the file is not generated.

      -c dir
      The name of the directory (which must exist) into which all of the generated C or C++ code is placed. By default no code is generated.

      -d file
      The name of the documentation file to generate. Documentation is included in specification files using the %Doc and %ExportedDoc directives. By default the file is not generated.

      -e
      Support for C++ exceptions is enabled. The causes all calls to C++ code to be enclosed in try/catch blocks and C++ exceptions to be converted to Python exceptions. By default exception support is disabled.

      -I dir
      The directory is added to the list of directories searched when looking for a specification file given in an %Include or %Import directive. This option may be given any number of times.

      -j number
      The generated code is split into the given number of files. This make it easier to use the parallel build facility of most modern implementations of make. By default 1 file is generated for each C structure or C++ class.

      -r
      Debugging statements that trace the execution of the bindings are automatically generated. By default the statements are not generated.

      -s suffix
      The suffix to use for generated C or C++ source files. By default .c is used for C and .cpp for C++.

      -t tag
      The SIP version tag (declared using a %Timeline directive) or the SIP platform tag (declared using the %Platforms directive) to generate code for. This option may be given any number of times so long as the tags do not conflict.

      -w
      The display of warning messages is enabled. By default warning messages are disabled.

      -x feature
      The feature (declared using the %Feature directive) is disabled.

      -z file
      The name of a file containing more command line options.

      (3) 輸入:
        輸入為規(guī)范文件。
        我們通過一個(gè)簡(jiǎn)單的規(guī)范文件示例來說明規(guī)范文件語法。假定有一個(gè)C++庫實(shí)現(xiàn)了Word類。類有一個(gè)構(gòu)造器,構(gòu)造器以一個(gè)\0結(jié)束的字符串作為唯一參數(shù)。類有一個(gè)叫做reverse()的無參方法,它返回一個(gè)\0結(jié)束的字符串。
        類的接口在頭文件word.h中定義,如下所示:
      // Define the interface to the word library.
      class Word {
        const char *the_word;
      public:
        Word(const char *w);
        char *reverse() const;
      };

        相應(yīng)的SIP規(guī)范文件如下所示:
      // Define the SIP wrapper to the word library.
      %Module word 0
      class Word {
      %TypeHeaderCode
      #include "word.h"
      %End
      public:
        Word(const char *);
        char *reverse() const;
      };

        SIP 使用指示器(Directives)來進(jìn)行C++特性的映射。指示器主要包括:
      %AccessCode
      %CModule 實(shí)現(xiàn)的是C模塊,并定義模塊名稱;
      %ConvertFromTypeCode 將C/C++類型轉(zhuǎn)換為Python類型;
      %ConvertToSubClassCode 同上(基于RTTI);
      %ConvertToTypeCode 同上;
      %Copying 添加的手寫代碼會(huì)包含到SIP生成的代碼文件頭中;
      %Doc   可以由命令提取出文檔信息;
      %End   標(biāo)識(shí)包含代碼或文本塊結(jié)束標(biāo)志;
      %ExportedDoc 可被import的文檔;
      %Feature 與%If、% Platforms、%Timeline一起使用,控制規(guī)范文件中一些部分是否被處理;
      %If
      %Import   導(dǎo)入其它模塊的規(guī)范文件;
      %Include 包括其它文件;
      %License 用來實(shí)現(xiàn)可選的執(zhí)行字典,包括Licensee, Signature, Timestamp和Type注解;
      %MappedType 定義自動(dòng)類型轉(zhuǎn)換映射表;
      %MethodCode 全局函數(shù)、類方法、運(yùn)算符、構(gòu)造和解析等的實(shí)現(xiàn)代碼;
      %Module   實(shí)現(xiàn)的是C++模塊,并定義模塊名稱;
      %ModuleCode 編寫能夠被其它模塊調(diào)用的函數(shù)代碼;
      %ModuleHeaderCode 被生成的所有文件包含的函數(shù)體聲明;
      %OptionalInclude 作用同%Include,但打開出錯(cuò)時(shí)繼續(xù)處理;
      %Platforms 配合%If,設(shè)置平臺(tái)信息;
      %PostInitialisationCode 編寫模塊調(diào)入初始化后立即執(zhí)行的代碼;
      %PreInitialisationCode 編寫模塊調(diào)入初始化前執(zhí)行的代碼;
      %Timeline 配合%If,設(shè)置版本信息;
      %TypeCode 標(biāo)注類或結(jié)構(gòu)中的函數(shù),使其可以被其它結(jié)構(gòu)或類調(diào)用;
      %TypeHeaderCode 定義結(jié)構(gòu)或類中將包含的頭文件,使得頭文件中類型可以被使用;
      %VirtualCatcherCode 虛函數(shù)實(shí)現(xiàn)相關(guān)的標(biāo)識(shí)。

        SIP使用注解(Annotations)來進(jìn)行參數(shù)和函數(shù)的高級(jí)說明。包括參數(shù)注解、類注解、函數(shù)注解、enum注解、license注解和變量注解。注解有自己的類型和相應(yīng)的可選值。舉例如下:
        在Python中,函數(shù)參數(shù)類型不匹配時(shí)能夠自動(dòng)調(diào)整為匹配,但在C/C++中將會(huì)出錯(cuò)。若在參數(shù)后添加Constrained注解將會(huì)解決這個(gè)問題。
      void foo(double);
      void foo(int);
      ================================================
      void foo(double /Constrained/);
      void foo(int);

      (4) 輸出:
        一系列生成文件,供編譯連接成為共享庫。

      3. Boost
      1)簡(jiǎn)介
        Boost是一套開放源代碼、高度可移植的C++庫,由C++標(biāo)準(zhǔn)委員會(huì)庫工作組發(fā)起。主要有以下一些特點(diǎn):
      Ø   支持正則表達(dá)式和各種字符類型(如char、wchar_t及自定義字符類型);
      Ø   支持多線程(跨平臺(tái)多線程庫);
      Ø   支持?jǐn)?shù)據(jù)結(jié)構(gòu)"圖",以及即將加入標(biāo)準(zhǔn)的hash_set、hash_map、hash_multiset、hash_multimap等,C++對(duì)數(shù)據(jù)結(jié)構(gòu)的支持已近完備;
      Ø   支持Python語言的擴(kuò)展;
      Ø   智能指針,與std::auto_ptr一起使用,可杜絕內(nèi)存泄露,且高效;
      Ø   支持循環(huán)冗余的CRC、元組tuple、可容納不同類型值的any等;
      Ø   還在迅速擴(kuò)大中,部分內(nèi)容有望進(jìn)入C++標(biāo)準(zhǔn)庫。

        Boost.Python,一個(gè)C++庫,能夠在C++和Python程序之間無縫連接。而且不需要任何額外的工具——只要你的C++編譯器。不必為了wrap而修改C++代碼,使用簡(jiǎn)單。
        當(dāng)前版本已經(jīng)被重寫,具有更靈活方便的接口和新的功能。包括:
      Ø   引用和指針
      Ø   Globally Registered Type Coercions
      Ø   自動(dòng)跨模塊的類型轉(zhuǎn)換
      Ø   有效的函數(shù)重載
      Ø   C++到Python的異常轉(zhuǎn)換
      Ø   默認(rèn)參數(shù)
      Ø   Keyword Arguments
      Ø   在C++中使用Python對(duì)象
      Ø   Exporting C++ Iterators as Python Iterators
      Ø   Documentation String

      2)使用
        使用步驟包括:
      Ø   寫C++源程序;
      Ø   寫C++ wrapper;
      Ø   使用bjam對(duì)wrapper進(jìn)行build;
      Ø   在python中使用。

      3)程序舉例:
      (1) 簡(jiǎn)單的C++函數(shù):
      char const* greet()
      {
      return "hello, world";
      }
        可以被寫成如下的Boost.Python wrapper:
      #include
      using namespace boost::python;

      BOOST_PYTHON_MODULE(hello)
      {
      def("greet", greet);
      }
        然后將它構(gòu)建成共享庫,便在Python中加以使用:
      >>> import hello
      >>> print hello.greet()
      hello, world

      (2) 類和結(jié)構(gòu)
      struct World
      {
      World(std::string msg): msg(msg) {} // added constructor
      void set(std::string msg) { this->msg = msg; }
      std::string greet() { return msg; }
      std::string msg;
      };
        它的wrapper文件為:
      #include
      using namespace boost::python;

      BOOST_PYTHON_MODULE(hello)
      {
      class_("World", init())
      .def("greet", &World::greet)
      .def("set", &World::set)
      ;
      }

      (3) 類的繼承
      struct Base { virtual ~Base(); };
      struct Derived : Base {};
        它的wrapper文件為:
      class_("Base")
      /*...*/
      ;
      class_ >("Derived")
      /*...*/
      ;

      五、總結(jié)
        本文只是對(duì)幾個(gè)擴(kuò)展工具的簡(jiǎn)單介紹,對(duì)每種工具將在后續(xù)文章中陸續(xù)加以說明,并附以代碼。

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多