C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  423 随笔 :: 0 文章 :: 454 评论 :: 0 Trackbacks


boost文档翻译 ( http://boost.everydo.com/ )


目前已完成:any, array, assign, bind & mem_fn, call_traits, compressed_pair, concept_check, conversion, crc, dynamic_bitset, enable_if, foreach, format, function, in_place_factory & typed_in_place_factory, io_state_savers, iostreams, iterator, lambda, minmax, mpl, multi_index, operators, preprocessor, program_options, property_map, range, rational, ref, smart_ptr, serialization, static_assert, timer, tokenizer, tribool, tuple, type_traits, typeof, utility, value_initialized
正在进行:functional/hash, graph, math, multi_array, regex, python, spirit, string_algo, thread, variant, wave

Boost.Python Build and Test HOWTO


1   Requirements

1   要求

Boost.Python requires Python 2.21 or newer.

Boost.Python要求Python 2.21 更高版

2   Background

2   背景

There are two basic models for combining C++ and Python:

  • extending, in which the end-user launches the Python interpreterexecutable and imports Python "extension modules" written in C++.Think of taking a library written in C++ and giving it a Pythoninterface so Python programmers can use it.  From Python, thesemodules look just like regular Python modules.
  • embedding, in which the end-user launches a program writtenin C++ that in turn invokes the Python interpreter as a librarysubroutine.  Think of adding scriptability to an existingapplication.


  • 扩展:最终用户运行Python解译器程序,并导入用C++编写的Python“扩展模块”。想像一个C++写的库,给它一个Python接口,这样Python程序员就可以使用它。从Python来看,这些模块就像是常规的Python模块。
  • 内嵌:最终用户运行C++写的程序,反过来调用Python解译器,就像调用一个库函数。想像一下为现有的应用程序加入脚本能力。

The key distinction between extending and embedding is the locationof the C++ main() function: in the Python interpreter executable,or in some other program, respectively.  Note that even whenembedding Python in another program, extension modules are oftenthe best way to make C/C++ functionality accessible to Pythoncode, so the use of extension modules is really at the heart ofboth models.

扩展和内嵌的关键性区别是,C++  main()函数的位置是在Python解译器程序中,还是在其他程序中? 注意,即使是在程序中内嵌Python,扩展模块往往是Python代码利用C/C++功能最好的方式,所以,这两种模式实际上是以扩展模块的使用为中心的。

Except in rare cases, extension modules are built asdynamically-loaded libraries with a single entry point, which meansyou can change them without rebuilding either the other extensionmodules or the executable containing main().


3   No-Install Quickstart

3   免安装快速入门

There is no need to "install Boost" in order to get started usingBoost.Python.  These instructions use Boost.Build projects,which will build those binaries as soon as they're needed.  Yourfirst tests may take a little longer while you wait forBoost.Python to build, but doing things this way will save you fromworrying about build intricacies like which library binaries to usefor a specific compiler configuration and figuring out the rightcompiler options to use yourself.



Of course it's possible to use other build systems tobuild Boost.Python and its extensions, but they are notofficially supported by Boost.  Moreover 99% of all "I can'tbuild Boost.Python" problems come from trying to use anotherbuild system without first following these instructions.


If you want to use another system anyway, we suggest that youfollow these instructions, and then invoke bjam with the

-a -ofilename

options to dump the build commands it executes to a file, soyou can see what your alternate build system needs to do.


-a -ofilename


3.1   Basic Procedure

3.1   基本过程

  1. Get Boost; see sections 1 and 2 [Unix/Linux, Windows] of theBoost Getting Started Guide.


  2. Get the bjam build driver.  See section 5 [Unix/Linux,Windows] of the Boost Getting Started Guide.


  3. cd into the libs/python/example/quickstart/ directory of yourBoost installation, which contains a small example project.


  4. Invoke bjam.  Replace the "stage" argument from theexample invocation from section 5 of the Getting StartedGuide with "test," to build all the test targets.  Also addthe argument "--verbose-test" to see the output generated bythe tests when they are run.

    调用bjam。将入门指南第5节例示的调用命令中的“stage”参数替换为“test”,来构建所有测试目标。  同时添加参数“--verbose-test”来查看测试运行时生成的输出。

    On Windows, your bjam invocation might look something like:


    C:\boost_1_34_0\…\quickstart> bjam toolset=msvc --verbose-test test

    and on Unix variants, perhaps,


    ~/boost_1_34_0/…/quickstart$ bjam toolset=gcc --verbose-test test

Note to Windows Users


For the sake of concision, the rest of this guide will useunix-style forward slashes in pathnames instead of thebackslashes with which you may be more familiar.  The forwardslashes should work everywhere except in Command Promptwindows, where you should use backslashes.


If you followed this procedure successfully, you will have built anextension module called extending and tested it by running aPython script called test_extending.py.  You will also havebuilt and run a simple application called embedding that embedspython.


3.2   In Case of Trouble

3.2   如果遇到问题

If you're seeing lots of compiler and/or linker error messages,it's probably because Boost.Build is having trouble finding yourPython installation.  You might want to pass the--debug-configuration option to bjam the first few timesyou invoke it, to make sure that Boost.Build is correctly locatingall the parts of your Python installation.  If it isn't, considerConfiguring Boost.Build as detailed below.

如果你见到大量编译或连接的错误信息,那可能是因为Boost.Build无法找到你的Python安装。你也许要在最初几次调用bjam时,传入--debug-configuration参数,以确保Boost.Build正确定位了所有Python组件。 如果不是,请考虑配置Boost.Build

If you're still having trouble, Someone on one of the followingmailing lists may be able to help:


3.3   In Case Everything Seemed to Work

3.3   如果一切都好

Rejoice!  If you're new to Boost.Python, at this point it might bea good idea to ignore build issues for a while and concentrate onlearning the library by going through the tutorial and perhapssome of the reference documentation, trying out what you'velearned about the API by modifying the quickstart project.


3.4   Modifying the Example Project

3.4   修改示例工程

If you're content to keep your extension module forever in onesource file called extending.cpp, inside your Boostdistribution, and import it forever as extending, then you canstop here.  However, it's likely that you will want to make a fewchanges.  There are a few things you can do without having to learnBoost.Build in depth.

如果你满足于此,扩展模块的源文件永远是extending.cpp,位于Boost发布目录中,并永远按extending导入,那么你就可以到此为止。 不过很可能是,你会想作一些变动。有许多事你可以做,而无须深入学习Boost.Build

The project you just built is specified in two files in the currentdirectory: boost-build.jam, which tells bjam where it canfind the interpreted code of the Boost build system, andJamroot, which describes the targets you just built.  Thesefiles are heavily commented, so they should be easy to modify.Take care, however, to preserve whitespace.  Punctuation such as; will not be recognized as intended by bjam if it is notsurrounded by whitespace.


Relocate the Project


You'll probably want to copy this project elsewhere so you canchange it without modifying your Boost distribution.  To do that,simply


  1. copy the entire libs/python/example/quickstart/ directoryinto a new directory.
  2. In the new copies of boost-build.jam and Jamroot, locatethe relative path near the top of the file that is clearlymarked by a comment, and edit that path so that it refers to thesame directory your Boost distribution as it referred to whenthe file was in its original location in thelibs/python/example/quickstart/ directory.
  1. 复制整个libs/python/example/quickstart/目录到一个新的目录。
  2. 在新的boost-build.jamJamroot副本中,靠近文件顶部,找到由一条注释清楚标注的相对路径,然后编辑这个路径,让它指向Boost发布目录,与它原来(当文件在libs/python/example/quickstart/目录时)所指目录相同。

For example, if you moved the project from/home/dave/boost_1_34_0/libs/python/example/quickstart to/home/dave/my-project, you could change the first path inboost-build.jam from






and change the first path in Jamroot from






Add New or Change Names of Existing Source Files


The names of additional source files involved in building yourextension module or embedding application can be listed inJamroot right alongside extending.cpp or embedding.cpprespectively.  Just be sure to leave whitespace around eachfilename:


… file1.cpp file2.cpp file3.cpp …

Naturally, if you want to change the name of a source file you cantell Boost.Build about it by editing the name in Jamroot.


Change the Name of your Extension Module


The name of the extension module is determined by two things:


  1. the name in Jamroot immediately following python-extension, and
  2. the name passed to BOOST_PYTHON_MODULE in extending.cpp.
  1. Jamroot中紧跟python-extension的名字,和
  2. extending.cpp中传给BOOST_PYTHON_MODULE的名字。

To change the name of the extension module from extending tohello, you'd edit Jamroot, changing


python-extension extending : extending.cpp ;



python-extension hello : extending.cpp ;

and you'd edit extending.cpp, changing






4   Installing Boost.Python on your System

4   在系统上安装Boost.Python

Since Boost.Python is a separately-compiled (as opposed toheader-only) library, its user relies on the services of aBoost.Python library binary.


If you need a regular installation of the Boost.Python librarybinaries on your system, the Boost Getting Started Guide willwalk you through the steps of creating one.  If building binariesfrom source, you might want to supply the --with-pythonargument to bjam (or the --with-libraries=python argumentto configure), so only the Boost.Python binary will be built,rather than all the Boost binaries.


5   Configuring Boost.Build

5   配置Boost.Build

As described in the Boost.Build reference manual, a file calleduser-config.jam in your home directory6 is used tospecify the tools and libraries available to the build system. Youmay need to create or edit user-config.jam to tell Boost.Buildhow to invoke Python, #include its headers, and link with itslibraries.


Users of Unix-Variant OSes

类Unix OS用户

If you are using a unix-variant OS and you ran Boost'sconfigure script, it may have generated auser-config.jam for you.4 If your configure/make sequence was successful and Boost.Python binarieswere built, your user-config.jam file is probably alreadycorrect.

如果你使用的是类Unix操作系统,并且你运行了Boost configure脚本,它可能已经为你生成了一个user-config.jam4。如果你configure/make就能成功构建Boost.Python,你的user-config.jam文件可能已经是正确的了。

If you have one fairly "standard" python installation for yourplatform, you might not need to do anything special to describe it.  Ifyou haven't configured python in user-config.jam (and you don'tspecify --without-python on the Boost.Build command line),Boost.Build will automatically execute the equivalent of


import toolset : using ;
using python ;

which automatically looks for Python in the most likely places.However, that only happens when using the Boost.Python project file(e.g. when referred to by another project as in the quickstartmethod).  If instead you are linking against separately-compiledBoost.Python binaries, you should set up a user-config.jam filewith at least the minimal incantation above.

这会让它在最有可能的地方自动寻找Python。 不过,这只会发生在当使用Boost.Python项目文件时(例如,当被另一个项目引用时,如快速入门所示方法)。反之,如果你链接单独编译的Boost.Python二进制,你应该建立一个user-config.jam文件,至少包含以上最少量的咒语。

5.1   Python Configuration Parameters

5.1   Python配置参数

If you have several versions of Python installed, or Python isinstalled in an unusual way, you may want to supply any or all ofthe following optional parameters to using python.

如果你安装了多个Python,或Python以一个不寻常的方式安装,你可能要向using python提供下列部分或全部可选参数。

the version of Python to use.  Should be in Major.Minorformat, for example, 2.3.  Do not include the subminorversion (i.e. not 2.5.1).  If you have multiple Pythonversions installed, the version will usually be the onlyconfiguration argument required.


preferably, a command that invokes a Python interpreter.Alternatively, the installation prefix for Python libraries andheader files.  Only use the alternative formulation if there isno appropriate Python executable available.


the #include paths for Python headers.  Normally the correctpath(s) will be automatically deduced from version and/orcmd-or-prefix.


the path to Python library binaries.  On MacOS/Darwin,you can also pass the path of the Python framework.  Normally thecorrect path(s) will be automatically deduced from versionand/or cmd-or-prefix.


if specified, should be a set of Boost.Buildproperties that are matched against the build configuration whenBoost.Build selects a Python configuration to use.  See examplesbelow for details.


A string to append to the name of extensionmodules before the true filename extension.  You almost certainlydon't need to use this.  Usually this suffix is only used whentargeting a Windows debug build of Python, and will be setautomatically for you based on the value of the<python-debugging> feature.  However, at least one Linuxdistribution (Ubuntu Feisty Fawn) has a specially configuredpython-dbg package that claims to use such a suffix.

一个字符串,用来附加到扩展模块名上(在真实的文件扩展名之前)。你几乎肯定不需要用到这个。通常这个后缀只用于针对Windows的Python调试版,并且,它会基于<python-debugging>特性的值自动设定。不过,至少有一个Linux发行版(Ubuntu Feisty Fawn),有一个特别配置的python-dbg包,声称使用了这样的后缀。

5.2   Examples

5.2   例子

Note that in the examples below, case and especially whitespace aresignificant.


  • If you have both python 2.5 and python 2.4 installed,user-config.jam might contain:

    如果你同时安装了python 2.5和python 2.4,user-config.jam可能包含:

    using python : 2.5 ;  # Make both versions of Python available

    using python : 2.4 ;  # To build with python 2.4, add python=2.4
                          # to your command line.

    The first version configured (2.5) becomes the default.  To buildagainst python 2.4, add python=2.4 to the bjam command line.

    第一个配置的版本(2.5)将成为默认值。如果要使用python 2.4构建,请在bjam命令行中添加python=2.4

  • If you have python installed in an unusual location, you mightsupply the path to the interpreter in the cmd-or-prefixparameter:


    using python : : /usr/local/python-2.6-beta/bin/python ;
  • If you have a separate build of Python for use with a particulartoolset, you might supply that toolset in the conditionparameter:


    using python ;  # use for most toolsets

    # Use with Intel C++ toolset
    using python
         : # version
         : c:\\Devel\\Python-2.5-IntelBuild\\PCBuild\\python # cmd-or-prefix
         : # includes
         : # libraries
         : <toolset>intel # condition
  • If you have downloaded the Python sources and built both thenormal and the "python debugging" builds from source onWindows, you might see:


    using python : 2.5 : C:\\src\\Python-2.5\\PCBuild\\python ;
    using python : 2.5 : C:\\src\\Python-2.5\\PCBuild\\python_d
      : # includes
      : # libs
      : <python-debugging>on ;
  • You can set up your user-config.jam so a bjam built under Windowscan build/test both Windows and Cygwin python extensions.  Just pass<target-os>cygwin in the condition parameterfor the cygwin python installation:


    # windows installation
    using python ;

    # cygwin installation
    using python : : c:\\cygwin\\bin\\python2.5 : : : <target-os>cygwin ;

    when you put target-os=cygwin in your build request, it should buildwith the cygwin version of python:5


    bjam target-os=cygwin toolset=gcc

    This is supposed to work the other way, too (targeting windowspython with a Cygwin bjam) but it seems as though the support inBoost.Build's toolsets for building that way is broken at thetime of this writing.

    另一种方式应该也行(使用Cygwin上的bjam,以windows python为目标),但在本文写作之时,Boost.Build的工具集对那种构建方式的支持好像有问题。

  • Note that because of the way Boost.Build currently selects targetalternatives, you might have be very explicit in your buildrequests.  For example, given:


    using python : 2.5 ; # a regular windows build
    using python : 2.4 : : : : <target-os>cygwin ;

    building with

    bjam target-os=cygwin

    will yield an error.  Instead, you'll need to write:


    bjam target-os=cygwin/python=2.4

6   Choosing a Boost.Python Library Binary

6   选择Boost.Python二进制库

If—instead of letting Boost.Build construct and link with the rightlibraries automatically—you choose to use a pre-built Boost.Pythonlibrary, you'll need to think about which one to link with.  TheBoost.Python binary comes in both static and dynamic flavors.  Takecare to choose the right flavor for your application.2


6.1   The Dynamic Binary

6.1   动态二进制

The dynamic library is the safest and most-versatile choice:


  • A single copy of the library code is used by all extensionmodules built with a given toolset.3
  • The library contains a type conversion registry.  Because oneregistry is shared among all extension modules, instances of aclass exposed to Python in one dynamically-loaded extensionmodule can be passed to functions exposed in another such module.
  • 用特定工具集构建的所有扩展模块,都使用同一份库代码。3
  • 库包含一个类型转换注册表。因为所有扩展模块共享一个注册表,所以,在一个动态装载的扩展模块中,导出到Python的类实例,可以传给另一个动态模块中导出的函数。

6.2   The Static Binary

6.2   静态二进制

It might be appropriate to use the static Boost.Python library inany of the following cases:


  • You are extending python and the types exposed in yourdynamically-loaded extension module don't need to be used by anyother Boost.Python extension modules, and you don't care if thecore library code is duplicated among them.
  • You are embedding python in your application and either:
    • You are targeting a Unix variant OS other than MacOS or AIX,where the dynamically-loaded extension modules can "see" theBoost.Python library symbols that are part of the executable.
    • Or, you have statically linked some Boost.Python extensionmodules into your application and you don't care if anydynamically-loaded Boost.Python extension modules are able touse the types exposed by your statically-linked extensionmodules (and vice-versa).
  • 你是在扩展Python,并且,你动态加载的扩展模块中导出的类型,不需要被其他Boost.Python扩展模块使用,你也不关心核心库代码是否在它们中间重复。
  • 你是在应用程序中内嵌Python,并且:
    • 你的目标是MacOS或AIX以外的类Unix OS,在那里,动态加载的扩展模块,可以“看见”可执行文件中Boost.Python库的符号。
    • 或者,你已经静态链接了一些Boost.Python扩展模块到你的应用程序,并且你不关心动态加载的Boost.Python扩展模块,是否能够使用你静态链接的扩展模块所导出的类型(反之亦然)。

7   #include Issues

7   #include问题

  1. If you should ever have occasion to #include "python.h"directly in a translation unit of a program using Boost.Python,use #include "boost/python/detail/wrap_python.hpp" instead.It handles several issues necessary for use with Boost.Python,one of which is mentioned in the next section.
  2. Be sure not to #include any system headers beforewrap_python.hpp.  This restriction is actually imposed byPython, or more properly, by Python's interaction with youroperating system.  Seehttp://docs.python.org/ext/simpleExample.html for details.
  1. 在使用Boost.Python的程序中,如果你需要在某个翻译单元中直接#include "python.h",请改为使用#include "boost/python/detail/wrap_python.hpp"。它处理了Boost.Python使用中几个必要问题,其中一个将在接下来的一节中提到。
  2. wrap_python.hpp之前,千万不要#include任何系统头文件。这一限制实际上是由Python强加的,更严格地说,是由Python与你的操作系统相互作用造成的。详见http://docs.python.org/ext/simpleExample.html

8   Python Debugging Builds

8   Python调试版

Python can be built in a special "python debugging" configurationthat adds extra checks and instrumentation that can be very usefulfor developers of extension modules.  The data structures used bythe debugging configuration contain additional members, so aPython executable built with python debugging enabled cannot beused with an extension module or library compiled without it, andvice-versa.


Since pre-built "python debugging" versions of the Pythonexecutable and libraries are not supplied with most distributionsof Python,7 and we didn't want to force our usersto build them, Boost.Build does not automatically enable pythondebugging in its debug build variant (which is the default).Instead there is a special build property calledpython-debugging that, when used as a build property, willdefine the right preprocessor symbols and select the rightlibraries to link with.


On unix-variant platforms, the debugging versions of Python's datastructures will only be used if the symbol Py_DEBUG is defined.On many windows compilers, when extension modules are built withthe preprocessor symbol _DEBUG, Python defaults to forcelinking with a special debugging version of the Python DLL.  Sincethat symbol is very commonly used even when Python is not present,Boost.Python temporarily undefines _DEBUG when Python.his #included from boost/python/detail/wrap_python.hpp - unlessBOOST_DEBUG_PYTHON is defined.  The upshot is that if you want"python debugging" and you aren't using Boost.Build, you should makesure BOOST_DEBUG_PYTHON is defined, or python debugging will besuppressed.

在类Unix平台上,仅当定义了Py_DEBUG符号时,才会使用调试版Python的数据结构。在许多Windows编译器上,当扩展模块用预处理符号_DEBUG构建时,Python默认会强制链接一个特殊的,调试版本的Python DLL。由于这个符号很常用(甚至没有Python时),所以,在boost/python/detail/wrap_python.hpp中包含Python.h时,Boost.Python暂时取消了_DEBUG定义——除非定义了BOOST_DEBUG_PYTHON。其结果是,如果你想要“Python调试”,并且你没有用Boost.Build,你务必定义BOOST_DEBUG_PYTHON,不然python调试会被禁用。

9   Testing Boost.Python

9   测试Boost.Python

To run the full test suite for Boost.Python, invoke bjam in thelibs/python/test subdirectory of your Boost distribution.

在Boost的libs/python/test子目录下, 调用bjam,以运行Boost.Python完整的测试包。

10   Notes for MinGW (and Cygwin with -mno-cygwin) GCC Users

10   MinGW(及Cygwin -mno-cygwin)上GCC用户注意事项

If you are using a version of Python prior to 2.4.1 with a MinGWprior to 3.0.0 (with binutils-2.13.90-20030111-1), you will need tocreate a MinGW-compatible version of the Python library; the oneshipped with Python will only work with a Microsoft-compatiblelinker. Follow the instructions in the "Non-Microsoft" section ofthe "building Extensions: Tips And Tricks" chapter in InstallingPython Modules to create libpythonXX.a, where XXcorresponds to the major and minor version numbers of your Pythoninstallation.

如果你正在使用Python 2.4.1,MinGW 3.0.0(和binutils-2.13.90-20030111-1)之前的版本,您将需要创建一个与MinGW兼容的Python库;Python发行随带的库只能用于微软兼容的连接器。请转到安装Python模块,“构建扩展:提示和技巧”一章,“非微软”一节,按照指示来创建libpythonXX.a,其中XX为你的Python安装的主要和次要版本号。

[1] Note that although we tested earlier versions ofBoost.Python with Python 2.2, and we don't think we've doneanything to break compatibility, this release of Boost.Pythonmay not have been tested with versions of Python earlier than2.4, so we're not 100% sure that python 2.2 and 2.3 aresupported.

注意,尽管我们在Python 2.2上测试过Boost.Python的早期版本,并且我们认为我们没有破坏兼容性,但本次发行的Boost.Python可能没有在Python 2.4以前的版本上测试过,所以我们不是100%的肯定能支持python 2.2和2.3。


Information about how to identify thestatic and dynamic builds of Boost.Python:


[3] Because of the way most *nix platformsshare symbols among dynamically-loaded objects, I'm not certainthat extension modules built with different compiler toolsetswill always use different copies of the Boost.Python librarywhen loaded into the same Python instance.  Not using differentlibraries could be a good thing if the compilers have compatibleABIs, because extension modules built with the two librarieswould be interoperable.  Otherwise, it could spell disaster,since an extension module and the Boost.Python library wouldhave different ideas of such things as class layout. I wouldappreciate someone doing the experiment to find out whathappens.

在大多数*nix平台上,在动态装载的对象之间,由于符号共享方式的关系,用不同编译工具构建的扩展模块,当加载到同一Python实例时,我不能肯定,是否总是使用不同的Boost.Python库。如果编译器都具有兼容的ABI,那么,使用相同的库将是一件好事,因为用两个库构建的两个扩展模块将可以互操作。 否则将带来灾难,因为扩展模块和Boost.Python库,将对如类布局之类的事情,有不同的想法。如果有人做实验,以了解会发生什么,我将不胜感激。

[4] configure overwrites the existinguser-config.jam in your home directory(if any) after making a backup of the old version.


[5] Note that the <target-os>cygwin feature isdifferent from the <flavor>cygwin subfeature of the gcctoolset, and you might need handle both explicitly if you alsohave a MinGW GCC installed.

注意,特性<target-os>cygwin有别于gcc工具集的子特性<flavor>cygwin,如果你同时也安装了MinGW GCC,你可能需要明确处理这两个特性。


Windows users, your home directory can befound by typing:


into a command prompt window.


[7] On Unix and similar platforms, a debuggingpython and associated libraries are built by adding--with-pydebug when configuring the Python build. OnWindows, the debugging version of Python is generated bythe "Win32 Debug" target of the Visual Studio project in thePCBuild subdirectory of a full Python source code distribution.You may also find

在UNIX和类似平台上,在配置Python构建时添加--with-pydebug,就可以构建调试版Python及相关库。在Windows上,调试版本的Python,是在Visual Studio项目中,由“Win32 Debug”目标产生,该项目文件位于Python源代码发行目录的PCBuild子目录。你也可以找到

posted on 2008-01-17 15:14 金庆 阅读(3192) 评论(2)  编辑 收藏 引用 所属分类: 1. C/C++6. Python


# re: Boost.Python构建与测试HOWTO 2008-08-28 21:04 temp
翻译的奇烂!!!  回复  更多评论

# re: Boost.Python构建与测试HOWTO 2008-11-28 10:11 temp2
同意 ! 相当烂  回复  更多评论

【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理