ATL及COM线程的学习

来源:COM线程模型-套间_com套间关联多个线程-CSDN博客

首先,只要遵守COM规范,不用COM库也能编写COM程序,那相当于自己实现用到的COM库函数。本篇COM如果单独出现,指COM库。

1   进程、线程回顾

《WINDOWS核心编程》对进程和线程有深入解释,一个程序运行起来,需要一个进程作为容器。进程管理所有系统资源、内存、线程等等。线程是CPU的调度单位,有自己的栈和寄存器状态。程序最初创建的线程叫主线程,主线程可以创建子线程,子线程还可以创建子线程。

不同进程之间是无法直接通信的,因为它们在虚拟内存中的地址不一样。但操作系统通过LPC机制,可以完成不同进程之间的通信。

COM在进程间通信的方法是本地过程调用(LPC),因为操作系统知道各个进程的确切逻辑地址,所以操作系统可以完成这一点。不同进程间传递的参数需要调整,LPC技术可以完成普通数据的直接拷贝(甚至包括自定义类和指针),但对于接口参数,COM实现了IMarshal接口以调整。

为了可以用同样的方式和进程外、远程组件通信,客户端不直接和组件通信,而是和代理/存根通信,代理/存根是(而且必须是) DLL形式,能完成参数调整和LPC调用。代理存根不用自己写,系统会自动产生。

注:接口的调整,包括列集和散集两种marshal/unmarshal。

2   COM线程模型

2.1 分清模型与实现

    看过《Inside C++ Object Model》(中文名:深入C++对象模型;侯捷译)的人都知道,C++对象模型有三种,各家编译器都选择其中效率最高的一种实现出来。另外两种就留在了理论世界,实现出来没有太大意义。提这个的原因,就是为了弄清楚这一点:COM线程模型只是理论构想,是一种抽象的数学模型,还要COM库通过各种手段实现出来,才能为我们使用。

2.2 套间的由来

最开始的COM库,支持的使用组件的唯一模式是single-thread-per-process模式。这样就避免了多线程的同步,而且组件执行的线程肯定是创建它的线程。

然而组件对象真正的执行环境很复杂。COM组件的执行环境有两种:单线程环境Single-Thread,多线程环境Multi-Thread。单线程要考虑执行线程是否是创建组件的线程;多线程还要考虑并发、同步、死锁、竞争等问题。无论哪种环境,都要编写大量的代码以使COM组件对象正确的运行。

为了使程序员减轻痛苦,COM库决心提供一套机制来帮助程序员。如果我们都遵从这套机制,只要付出较少的劳动,就可以让组件对象和COM库一起完成工作。COM库这套机制的核心技术就是“套间技术”。

2.3 COM的多线程模型

2.3.1 COM库的规定

关于多线程问题方面,COM库做出了如下规则(不是COM标准,是COM库为了简化多线程编程中对组件的调用而制定的):

1. COM库提供两种套间,单线程套间和多线程套间,COM组件的编写者最好提供对应的属性(后面会提到),COM组件的使用者要在套间里创建和调用组件。

2. COM库对所有的调用进行参数调整(如果需要),不管是对进程内服务器的调用,还是对进程外服务器的调用。

3. 线程内调用、跨线程调用、跨进程调用都用统一的方式。需要用代理的会用代理。

如此COM规定了COM库、组件编写者、组件使用者三方合作关系。COM库进行协调关系,会根据组件的能力,在不同环境(套间)中创建和调用组件;编写者要说明组件可以生存的环境;调用者查询接口,合理调用。

2.3.2 单线程套间STA

Single-threadedApartments,一个套间只关联一个线程,COM库保证对象只能由这个线程访问(通过对象的接口指针调用其方法),其他线程不得直接访问这个对象(可以间接访问,但最终还是由这个线程访问)。

COM库实现了所有调用的同步,因为只有关联线程能访问COM对象。如果有N个调用同时并发,N-1个调用处于阻塞状态。对象的状态(也就是对象的成员变量的值)肯定是正确变化的,不会出现线程访问冲突而导致对象状态错误。

注意:这只是要求、希望、协议,实际是否做到是由COM决定的。这个模型很像Windows提供的窗口消息运行机制,因此这个线程模型非常适合于拥有界面的组件,像ActiveX控件、OLE文档服务器等,都应该使用STA的套间。

2.3.3 多线程套间MTA

MultithreadedApartments,一个套间可以对应多个线程,COM对象可以被多个线程并发访问。所以这个对象的作者必须在自己的代码中实现线程保护、同步工作,保证可以正确改变自己的状态。

这对于作为业务逻辑组件或干后台服务的组件非常适合。因为作为一个分布式的服务器,同一时间可能有几千条服务请求到达,如果排队进行调用,那么将是不能想象的。

注意:这也只是一个要求、希望、协议而已。

2.3.4 COM+新增NA

COM+为了进一步简化多线程编程,引入了中立线程套间概念。

NA/TNA/NTA,Neutral Apartment/Thread NeutralApartment / Neutral Threaded Apartment。这种套间只和对象相关联,没有关联的线程,因此任何线程都可以直接访问里面的对象,不存在STA的还是MTA的。

2.4 到底什么是套间

根据《COM技术内幕》的观点,COM没有定义自己新的线程模型,而是直接利用了Win32线程,或者说对其做了改造、包装。线程间的同步也是直接用的Win32 APIs。

《COM本质论》设这样定义的:套间定义了一组对象的逻辑组合,这些对象共享一组并发性和冲入限制。每个COM对象都属于某一个套间,一个套间可以包含多个COM对象。

MSDN上解释说,可以把进程中的组件对象想象为分成了很多组,每一组就是一个套间。属于这个套间的线程,可以直接调用组件,不属于这个套间的线程,要通过代理才能调用组件。

最直接的说,COM库为了实现简化多线程编程的构想,提出了套间概念。套间是一个逻辑上的概念,它把Win32里的线程、组件等,按照一定的规则结合在一起,并且以此提供了一种模式,用于多线程并发访问COM组件方面。可以把套间看作COM对象的管理者,它通过调度,切换COM对象的执行环境,保证COM对象的多线程调用正常运行。COM和线程不是包含关系,而是对应和关联关系。

3   第一方COM库:模型的实现

3.1 单线程套间STA

CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);这句代码创建了一个STA,然后套间把当前的线程和自己关联在一起,线程被标记为套间线程,只有这个线程能直接调用COM对象。

在创建套间的时候,COM创建了一个隐藏的窗口。关联线程对组件的调用直接通过接口指针调用方法;其他线程对套间里的对象的调用,都转变成对那个隐藏窗口发送消息,然后由这个隐藏窗口的消息处理函数来实际调用组件对象的方法。编写组件代码的时候,只需调用DispatchMessage即可将方法调用的消息和普通的消息区分开来(通过隐藏窗口的消息处理函数)。

由于窗口消息的处理是异步的,所以所有的调用都是依次进行的,不必考虑同步的问题。只要调用的时候,参数进行合理调整即可(COM库会做到这一点)。但是对于全局变量和静态变量,组件编写者还是要费心的。

一个STA只关联一个线程, single-thread-per-process模式只是STA的一个特例。使用这种模式的线程叫套间线程(Apartment Thread)。

3.2 多线程套间MTA

CoInitializeEx(NULL,COINIT_MULTITHREADED);第一次如此调用的时候,会创建一个MTA,然后套间把当前线程和自己关联在一起,线程被标记为自由线程。以后第二个线程再调用(在同一进程中)的时候,这个MTA会把第二个线程也关联在一起,并标记为自由线程。一个MTA可以关联多个线程。

所有的关联线程都可以调用套间中的组件。这就涉及到同步问题,需要组件编写者解决。

一个MTA可以关联一个或多个线程,这种模式下,COM组件自己要考虑同步问题。使用这种模式的这些线程叫做自由线程(FreeThread) 。

3.3 总结

一个进程可以有0个、1个或多个STA,还可以有0个或1个MTA。

一个线程,进入(或创建)套间后,不能改变套间模式;但可以退出套间,然后以另外的模式再进入(或创建)另一个套间。

在一个进程中,主套间是第一个被初始化的。在单线程的进程里,这是唯一的套间。调用参数在套间之间被调整,COM库通过消息机制处理同步。

如果你设计多个线程作为自由线程,所有的自由线程在同一个单独的套间中,参数被直接(不被列集)传递给这个套间的任何线程,而且你要处理所有的同步。

在既有自由线程又有套间线程的进程里,所有自由线程在一个套间里,而其他套间都是单线程套间。而进程是包含一个多线程套间和N个单线程套间的容器。

COM的线程模型为客户端和服务器提供了这样一种机制:让不同的线程协同工作。不同进程内,不同线程之间的对象调用也是被支持的。以调用者的角度来看,所有对进程外对象的调用都是一致的,而不管它在怎样的线程模型。以被调用者的角度来看,不管调用者的线程模型如何,所获得的调用都是一致的。

客户端和进程外对象之间的交互也很直接,即使它们使用了不同的线程模型,因为它们属于不同的进程。COM介入了客户端和服务器之间,通过标准的列集和RPC,并提供了跨线程操作的代码。

4   第二方COM组件的调用者

4.1 各种调用

4.1.1 同一线程中的调用

同步问题:不需要,调用者和组件在同一线程中,自然同步。

调整问题:不需要,COM库不需要任何介入,参数也不需要调整,组件也不必线程安全。

调用地点:当前线程

这是最简单的情况。

4.1.2 套间线程之间的调用

同步问题:COM库对调用进行同步。

调整问题:不管两个套间是否在同一进程,都需要调整。某些情况下,需要手动调整。

调用地点: 对象所在套间线程。

4.1.3 自由线程之间的调用

同步问题:COM不进行同步,组件自己同步。

调整问题:同一进程不调整,不同进程要调整。

调用地点:客户线程。

4.1.4 自由线程调用套间线程的组件

同步问题:COM库对调用进行同步。

调整问题:不管两个套间是否在同一进程,都需要调整。某些情况下,需要手动调整。

调用地点:套间线程

4.1.5 套间线程调用自由线程的组件

同步问题:COM不进行同步,组件自己同步。

调整问题:需要调整,同一进程,COM会优化调整。

调用地点:客户线程。

4.2 手工调整

如果通过COM方法,所有的参数都由COM库进行调整。有时候需要程序员手工对接口指针进行列集marshal和散集unmarshal,那就是在跨越套间边界,但没有通过COM库进行通信的时候。更明确的说,不通过COM接口函数,通过我们自己写的函数跨套间传递接口指针的时候。

情况一:跨套间传递接口指针。

情况二:类厂在另外的套间中,创建类实例,并传回给客户端的接口指针。

列集函数:CoMarshalInterThreadInterfaceInStream

散集函数:CoGetInterfaceAndReleaseStream 

5   第三方COM组件的编写者

组件将在哪种类型的套间中执行,是编写者决定的。对于进程外组件,要调用CoInitializeEx并指定参数,以显示确定套间类型。对于进程内的服务器来说,因为客户端已经调用CoInitializeEx产生套间了,为了允许进程内的服务器可以控制它们的套间类型,COM允许每个组件有自己不同的线程模型,并记录在注册表中。

HKEY_CLASSES_ROOT/CLSID/.../InprocServer32键值ThreadingModel

5.1 线程模型属性

组件编写者可以实现:同一个组件,既可以在STA中运行,也可以在MTA中运行,还可以在两中环境中同时存在。可以说组件有一种属性说明可以在哪种环境中生存,属性名叫做“线程模型”(相当于“隐藏”)也未尝不可。COM+里真正引入了这个属性,并叫做ThreadModel。这个属性可以有如下取值:

1. Main Thread Apartment

2. Single Thread Apartment(Apartment)

3. Free Thread Apartment (Free)

4. Any Apartment (Both)

5. Neutral Apartment (N/A)

5.2 对象在哪个套间创建

下表中第一列为套间种类,第一行为对象线程模型属性。那么,结果就是在这样的套间中创建这样的组件,组件在什么地方。在必要的时候,会创建一个代理,就是表中的宿主。

未指定

Apartment

Free

Both

Neutral

单线程

(非主)

主STA

当前套间

MTA

当前套间

NA

单线程

(主线程)

当前套间

当前套间

MTA

当前套间

NA

多线程

主STA

宿主STA

MTA

MTA

NA

Neutral

单线程

主线程套间

宿主STA

(本线程)

MTA

NA

NA

Neutral

多线程

主线程套间

宿主STA

MTA

NA

NA

5.3 属性的选择

原则是根据组件的功能选择:

如果组件做I/O,首选Free,因为可以相应其他客户端调用。

如果组件和用户交互,首选Apartment,保持消息依次调用。

COM+首选N/A。

如果没有定义,COM库默认为是Main Thread Apartment。

Apartment简单,Free强大但要自己同步。

6   鸣谢

《COM技术内幕》《COM本质论》《深入解析ATL》

6.1 MSDN2008

在MSDN 2008中相关文档的位置:

Win32和COM开发

  -组件开发

    -组件对象模型

     -SDK文档

       -COM

         -COM Fundamentals

           -Guide-Processes, Threads, and Apartments

Win32和COM开发

  -组件开发

   -COM+

     -SDK文档

       -COM+(组件服务)

         -COM+开发浏览

           -COM+ Contexts and Threading Models

6.2 COM线程模型

http://hi.baidu.com/zhangqiuxi/blog/item/ca7aa52b0311b4fbe6cd401e.html

6.3 理解 COM 套间

http://www.vckbase.com/document/viewdoc/?id=1597

6.4 泛说"COM线程模型"

http://blog.csdn.net/guogangj/archive/2007/09/06/1774280.aspx

6.5 附泛说一文

COM线程模型在COM相关的基础知识中应该算是难点,难的原因可能有这些:

1、需要对COM其它基础知识有较深的了解,因为这个论题几乎涉及到了COM所有其它的基础知识。

2、学习者得非常了解Win32本身的线程模型,因为在Windows中COM的线程模型在建立在Win32线程模型的基础上的。

3、COM线程模型所引用的概念十分抽象,不好理解。

如果你还没有掌握 1,2 所提到的知识点,你可以马上找一些书籍,迅速补充这些知识,如果你已经掌握了这些知识,那就给你的想象力上点油,轻松点。

6.5.1 开始想象

术语

公寓(Apartment)有的译文译作"套间"。这个术语抽象的是COM对象的生存空间,你还真的可以想象成公寓,线程就是住在公寓里的人。

单线程公寓(Single-ThreadedApartment STA) 这种房间是供有钱人住的单人间,设备齐全,服务周到。

多线程公寓(MultithreadedApartment MTA) 住在这种房间里的人条件就差多了,那么多人就挤在一个大房间里头,可是他们自强不息。个个健壮得不得了。

然后思考

单线程公寓与多线程公寓的本质差别有哪些?

如果另一个人要和住在单线程公寓的人通信,不能直接去找他,哪怕你也住在高贵的单人间。但你可以打电话。提醒一下,电话每次只能同时与一个人说话(他们还没有用到电话会议之类的服务)。住在多线程公寓的人他们的房间有个大窗子,如果住在单人间(单线程公寓)的人想与他们通信,来窗口说就行,而且这个窗子比你想的要大,可以同时让很多人对话。同一房间里的人不用说了,他们可以直通话。

6.5.2 回到现实

术语

1、公寓,如果从来就不用考虑线程同步的问题,就用不着这个概念了,可是 COM 决定支持强大的多线程,于是引入了这个概念,公寓决定了线程与外界通信的方式。每一个与COM对象打交道的线程必须先决定要进入哪种公寓。

2、单线程公寓,这种公寓本身只能包含一个线程,通过调用CoInitialize(NULL)进入。它有着与窗口类似的运作方式,回想一下窗口的运行方式:消息泵不断的从消息队列提取消息,然后调度给相应的窗口函数。这样做的好处是,窗口函数永远不会重入,也就是说永远不会有同步的问题。单线程公寓也用了同样的运作方式(所以该公寓中的线程的主函数必须有一个消息循环):对该公寓中线程所拥有的COM对象的调用被队列化,只有当一个调用结束后,另个调用才会开始。那么组件对象的代码也是永远不会重入。

3、多线程公寓,这种公寓可以包含任意多的线程(具体数目由操作系统决定)。一个进程里头只能包含一个这种公寓,所有调用CoInitializeEx(NULL, COINIT_MULTITHEADED)都会进入这个公寓。对该公寓中线程所拥有的COM对象的调用是直接的(先不考虑跨进程的情况),包括本公寓中的线程与其它的STA线程。

然后思考

单线程公寓与多线程公寓 的本质差别有哪些?

单线程公寓实现同步,有很多COM库的干预,包括将外部的调用转化成窗口消息,然后那个特别的隐藏窗口的窗口函数把窗口消息转化成COM对象的函数调用。这样的模型可以减小开发组件的难度,可是,却牺牲了效率。多线程公寓把实现同步任务全部交给了组件自己,所以在这种公寓中生存的COM对象必须足够健壮,考虑各种同步问题,不至于多个线程在调用对象的成员函数时会打架。

6.5.3 弄清它们的关系

弄清公寓,线程,对象的关系是很重要的,你弄清了吗?如果你没有弄清,那上面的这些也一定也是看得懵懵懂懂。公寓是这里面最大的单位,它是线程的容器。如果调用CoInitialize(0),COM库会创建一个STA(注意,是"创建"),你的线程将属于这个公寓,并且是这个公寓的唯一成员。如果CoInitializeEx(NULL, COINIT_MULTITHEADED),而且是第一个要求进入MTA的线程,COM库会创建一个MTA,其它后面调用 CoInitializeEx(NULL, COINIT_MULTITHEADED)的线程会直接进入(注意,我用的"进入")已有MTA。本来线程是一个运行的实体,不会分配资源,可是在 COM的线程模型里一个对象与创建它的线程是紧密相关的,称对象归属于某个线程,至于这种归属关系是在COM库内怎么管理,我们先不去管它,以后我们把线程A创建的对象说成是线程A的对象就行了(有一个例外,得说说,有一种Single 类型的COM对象,这种对象基实就是COM在提出线程模型前的产物,这种对象总是归属于主STA线程,即第一个调用CoInitialize(0)的线程。)

如有缪误,敬请指正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
中文名: 深入解析ATL(第2版) 原名: ATL Internals, 2nd Edition Working with ATL 8 别名: ATL 作者: (美)塔瓦瑞斯译者: 赖仪灵 曹雨田 资源格式: PDF 版本: 扫描版 出版社: 电子工业出版社书号: 9787121049859发行时间: 2007年11月01日 地区: 大陆 语言: 简体中文 简介: 编辑推荐 ATL的发明人Jim Springfield亲自作序推荐。   四位顶尖的Windows编程专家倾力合作,绝对经典再现。   COMATL开发人员的必备宝典。   深入分析ATL实现COM内幕细节,展示COM应用中的各类漂亮技巧。   ATL的经典指南现已更新到ATL 8和VisuaI Studio 2005:   四位顶尖的Windows编程专家在本书中系统地揭示了ATL的内部工作原理,他们解释了ATL是 如何工作的,以及为什么要以这样的方式工作。通过本书,客户端开发人员可以掌握ATL中的窗口、COM控件、MFC集成、Web服务代理生成等资源。服务端编程人员可以应用ATL的全COM服务器和对象服务、高吞吐量、高并发Web应用程序和服务的广泛支持。每个Windows开发人员都将从本书中学到强大的方法来增加应用程序的灵活性、减少负载、最大化程序的透明度和可控性。   ·通过图表、示例代码和ATL的内部实现代码来揭密ATL的内部原理。   ·遍历向导以简化在普通应用程序中的ATL开发。   ·掌握C++COMATL中的字符串使用技巧。   ·利用ATL的智能类型:CComPtr、CComQIPtr、CComBSTR和CComVariant。   ·理解并正确实现IUnknown。   ·创建能从COM服务器中暴露COM对象的粘合代码。   ·使用Canned Interface实现来支持对象的永久性、COM集合、枚举器和连接点。   ·使用ATL窗口类和控件建立独立的应用程序和UI组件。   ·使用ATL Servet开发可以运行在微软IIS上的Web应用程序。 虽然.NET系统从1998年才开始其发展进程。但它已经使很多开发人员的编程发生了革命性的变化,并在未来几年将持续得到改进。但是,COM编程(和 ATL)也依然非常有活力,对Microsoft内外的很多开发人员都非常重要。本书的第2版,与第1版一样,提供了您所需要的信息,使我们在这些技术上的投资也将获得最大的回报。                        ——Jim Springfield,ATL发明人 虽然ATL比较精深,但是这本书的讲解非常通俗易懂,语言比较简练,条理非常清楚。即使在读完这本书之后,它仍然可以作为参考书指导我们的开发和学习工作。我想,这就是好书的价值所在吧。            ——潘爱民,经典畅销书《深入解析Windows操作系统,第4版》译者 内容简介 本书主要介绍了ATL技术的原理、内部实现和应用技巧,由当今4 位顶尖的 Windows技术专家联合撰写。全书内容丰富,深入浅出,主要涵盖了ATL内部架构和实现方法、运用向导简化ATL开发、C++/COM/ATL中字符串的使用技巧、理解并正确实现IUnknown、充分利用ATL提供的Smart Types、撰写能够暴露COM服务器上COM对象的粘合代码、利用Canned Interface实现来支持对象持久化/COM群集/枚举、利用ATL Windows类建构独立的应用程序和UI组件等的技术内容。本书适合于广大Windows开发人员阅读参考,是ATL开发人员的必备权威参考书籍。 作者简介 Christopher Tavares,目前在微软工作,是模式与实践方面的专家。有着超过25年的编程经验,涉及的平台从Sinclair ZX-81到多CPU信号处理硬件。 目录: 第2版序 第1版序 前言 致谢 关于作者 联系博文视点 第1章 你好,ATL 1.1 什么是ATL 1.2 创建COM服务器 1.3 插入COM类 1.4 添加属性和方法 1.5 实现附加接口 1.6 脚本支持 1.7 添加永久性 1.8 添加和激发事件 1.9 使用窗口 1.10 COM控件 1.11 容纳控件 1.12 ATL Server Web项目 1.13 总结 第2章 字符串和文本 2.1 字符串数据类型、转换类和辅助函数 2.2 智能BSTR类CComBSTR 2.3 CComBSTR类 2.4 CString类 2.5 总结 第3章 ATL智能类型 3.1 智能VARIANT类CComVariant 3.2 智能SAFEARRAY类CComSafeArray 3.3 智能指针类CComPtr和CComQIPtr 3.4 智能指针类CAutoPtr和CAutoVectorPtr 3.5 ATL内存管理器 3.6 总结 第4章 ATL中的对象 4.1 实现IUnknown 4.2 ATL的层次 4.3 线程模型支持 4.4 IUnknow核心 4.5 我们的类 4.6 CComObject以及其他 4.7 ATL创建者 4.8 调试 4.9 总结 第5章 COM服务器 5.1 回顾COM服务器 5.2 对象映射表和CAtlModule类 5.3 对象映射表 5.4 对象映射类要求的方法 5.5 CAtlModule类 5.6 重游CComCoClass 5.7 ATL与C运行时 5.8 总结 第6章 接口映射表 6.1 回顾:COM的实体身份 6.2 表驱动的QueryInterface 6.3 多重继承 6.4 Tear-off接口 6.5 聚合:外部控制对象 6.6 接口映射表链 6.7 尽管说“不” 6.8 调试 6.9 扩展性 6.10 总结 第7章 ATL中的永久性 7.1 回顾COM的永久性 7.2 ATL的永久性实现类 7.3 属性映射表 7.4 永久性实现 7.5 其他永久性实现 7.6 使用永久性添加“按值列集”的语义 7.7 总结 第8章 集合和枚举器 8.1 COM集合和枚举接口 8.2 枚举数组 8.3 枚举标准的C++集合 8.4 集合 8.5 ATL数据类型的标准C++集合 8.6 ATL集合 8.7 对象模型 8.8 总结 第9章 连接点 9.1 回顾连接点 9.2 创建基于ATL的可连接对象 9.3 创建一个接收事件的对象 9.4 它是怎么工作的:杂乱的实现细节 9.5 总结 第10章 窗口 10.1 Windows应用程序的结构 10.2 CWindow 10.3 CWindowImpl 10.4 CDialogImpl 10.5 Windows控件包装类 10.6 CContainedWindow 10.7 总结 第11章 ActiveX控件 11.1 回顾ActiveX控件 11.2 BullsEye控件需求 11.3 使用ATL向导创建初始的控件 11.4 初始的BullsEye源文件 11.5 逐步开发BullsEye控件 11.6 总结 第12章 控件包容 12.1 控件是如何被包容的 12.2 基本的控件包容 12.3 在对话框中容纳控件 12.4 复合控件 12.5 HTML控件 12.6 ATL控件包容的限制 12.7 总结 第13章 你好,ATL Server:一个新型的C++ Web平台 13.1 微软Web平台(因特网信息服务) 13.2 可能是可以运行的最简单ISAPI扩展 13.3 封装ISAPI 13.4 ATL Server 13.5 ATL Server中的Web服务 13.6 总结 第14章 ATL Server内幕 14.1 ATL Server中的ISAPI实现 14.2 服务器响应文件 14.3 请求处理程序示例 14.4 输入处理 14.5 会话管理 14.6 数据缓存 14.7 总结 附录A 实例展示C++模板 A.1 模板的必要性 A.2 模板基础 A.3 不同类型的多态 A.4 函数模板 A.5 成员函数模板 A.6 总结 附录B ATL头文件 附录C 移植到ATL 8 C.1 字符串、字符集和转换 C.2 与MFC共享的类 C.3 实现COM服务器 C.4 ActiveX控件和控件容纳 C.5 ATL_MIN_CRT变化 C.6 总结 附录D 属性化ATL D.1 ATL Attributes的基础 D.2 属性化ATL的未来 D.3 总结 索引

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值