|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
自己的整个学习思路完全被老师的讲课思路所牵制,这样几节课听下来,恐怕自己的见解都应该是书里的知识点了,根本谈不上自身发现问题,分析问题,和解决问题能力的切实提高。在一样平常事情中,我看到过很多由分歧开辟职员编写的COM代码。我为很多富于制造性的利用COM的事情体例感应惊奇,有一些使COM事情的奇妙代码大概连Microsoft都没有想到。一样,看到一些毛病一次又一次地重犯,使我免不了跃跃欲试。这些毛病良多都与线程和平安有关,完整不成比例,而这也恰是COM文档材料中最短少的两个范畴。假如不细心企图,它们也是最大概碰到的并大概会绊住您的两个范畴。
本月的“超酷代码”专栏与之前的年夜多半专栏有所分歧。它并未供应一段可在您本人的使用程序中利用的超酷代码。相反,它将报告完成基于COM的使用程序的准确体例和毛病体例。它将报告一些来自困难理论的教导,和怎样制止落进已让很多COM开辟职员吃尽甜头的圈套。
鄙人面的篇幅中,您将读到八位程序员的记叙,这些教导都来自他们的疾苦履历。每一个故事都是实在的,但为了回护无辜者,名字都已隐往。我的目标是,经由过程这些实在的COM故事,使您不再重蹈其他COM程序员的复辙。它们还大概会匡助您在编写的代码中找出存在潜伏成绩的中央。不管情形怎样,我想您城市取得兴奋的浏览体验。
老是挪用CoInitialize(Ex)
不要在线程之间传送原始接口指针
STA线程必要动静轮回
单位模子对象必需回护共享数据
审慎启动用户
DCOM不适于防火墙
利用线程或异步伐用来制止DCOM超时设定太长
共享对象其实不简单
与我接洽
<br>老是挪用CoInitialize(Ex)
几个月前,我收到了一封伴侣的电子邮件,他就任于一家出名的硬件公司。他的公司编写了一个十分庞大的基于COM的使用程序,个中利用了很多历程内和当地(历程外)的COM组件。在入手下手时,使用程序创立了COM对象以服务于运转在多线程单位(MTA)中的各类客户端线程。该对象还能够托管给MTA,这意味着接口指针能够在客户端线程之间自在互换。在测试中,我的伴侣发明在使用程序筹办封闭之前,统统都举行得不错。然后,不知是甚么缘故原由,对Release的挪用(必需实行此挪用,以便准确开释客户端占用的接口指针)被锁定了。他的成绩是:“究竟是那里出了成绩?”
实在谜底十分复杂。使用程序的开辟职员其他都做得很对,只要一点破例,而这点又十分主要:他们没有在一切的客户端线程中挪用CoInitialize或CoInitializeEx。古代COM的基础准绳之一,就是每一个利用COM的线程都应当先挪用CoInitialize或CoInitializeEx来初始化COM。这条准绳是没法免去的。除其他事变之外,CoInitialize(Ex)应将线程放进单位中,并初始化主要的每线程形态信息(这关于COM的准确操纵是必须的)。挪用CoInitialize(Ex)失利一般会在使用程序性命期初期以失利的COMAPI函数的情势体现出来,最多见的是激活哀求。但偶然成绩很潜伏,直到统统都太晚了(比方对Release的挪用一往不复返了)才体现出来。当开辟小组将CoInitialize(Ex)挪用增加到一切打仗COM的线程以后,他们的成绩就水到渠成了。
具有取笑意义的是,Microsoft竟是COM程序员偶然不挪用CoInitialize(Ex)的缘故原由之一。Microsoft常识库中包括的一些文档中说,挪用CoInitialize(Ex)对基于MTA的线程来讲不是必须的(有关示例,请参阅文章Q150777)。是的,在良多情形下,我们能够跳过CoInitialize(Ex)而不会呈现成绩。可是,如许是不该该的,除非您晓得本人在干甚么,而且能够相对一定本人不会遭到负面影响。挪用CoInitialize(Ex)是没无害处的,因而我倡议COM程序员一直从某个与COM相干的线程中挪用它。
<br>不要在线程之间传送原始接口指针
我征询的首批COM项目之一就触及到一个包括100,000行代码的散布式使用程序,该程序是由美国西海岸的一个年夜型软件公司编写的。该使用程序在多个呆板上创立了数十个COM对象,并从客户端历程启动的背景线程中挪用这些对象。开辟小组碰到成绩了,挪用要末消散得无影无踪,要末在没有分明缘故原由的情形下失利。他们给我演示的最惊人的症状是:当一个挪用没法前往时,在统一台呆板上启动其他撑持COM的使用程序(包含MicrosoftPaint等)会频仍招致这些使用程序被锁定。
反省他们的代码后发明,他们违背了COM并发的一个基础划定规矩,就是说,假如一个线程要与另外一个线程共享一个接口指针,它应起首封送该接口指针。假如有需要,封送接口指针可以使COM创立一个新的代办署理(和一个新的信道对象,将代办署理和存根结对),以同意从另外一个单位向外挪用。欠亨过封送而将原始接口指针(内存中的一个32位地点)传送给另外一个线程,会绕过COM的并发机制,而且假如发送和吸收的线程位于分歧的单位中,将呈现各类不良举动。(在Windows2000中,因为两个对象能够共享一个单位,但又位于分歧的高低文中,因而假如线程位于统一个单位中,大概会使您堕入窘境。)典范的症状包含挪用失利和前往RPC_E_WRONG_THREAD_ERROR。
WindowsNT4.0和更高版本可使用一对名为CoMarshalInterThreadInterfaceInStream和CoGetInterfaceAndReleaseStream的API函数,在线程之间轻松地封送接口指针。假定您使用程序中的一个线程(线程A)创立了一个COM对象,继而吸收了一个IFoo接口指针,而且统一历程中的另外一个线程(线程B)想挪用这个对象。在筹办将接口指针传送给线程B时,线程A应当封送该接口指针,以下所示:- CoMarshalInterThreadInterfaceInStream(IID_IFoo,pFoo,&pStream);
复制代码 在CoMarshalInterThreadInterfaceInStream前往后,线程B就能够平安地作废封送该接口指针:- IFoo*pFoo;CoGetInterfaceAndReleaseStream(pStream,IID_IFoo,(void**)&pFoo);
复制代码 在这些示例中,pFoo是一个IFoo接口指针,pStream是一个IStream接口指针。COM在挪用CoMarshalInterThreadInterfaceInStream时初始化IStream接口指针,然后在CoGetInterfaceAndReleaseStream外部利用和开释该接口指针。实践上,您一般要利用一个事务或其他同步化基元来和谐这两个线程的举动—比方,让线程B晓得接口指针已筹办好,能够作废封送。
请注重,以这类体例封送接口指针不会呈现任何成绩,由于COM有充足的智能,在不必要举行封送时不会往封送(或从头封送)指针。假如在线程之间传送接口指针时如许做,利用COM就轻松多了。
假如挪用CoMarshalInterThreadInterfaceInStream和CoGetInterfaceAndReleaseStream看起来太贫苦,您还能够经由过程将接口指针放在全局接口表(GIT)中,并让其他线程往那边检索它们,从而完成在线程之间传送接口指针。从GIT中检索到的接口指针在被检索时会主动封送。更多信息,请参阅IGlobalInterfaceTable中的文档。请注重,GIT只存在于WindowsNT4.0ServicePack4及更高版本中。
<br>STA线程必要动静轮回
上一部分中形貌的使用程序另有另外一个致命缺点。看看您是不是能指出来。
这个特别的使用程序刚好是用MFC编写的。在一入手下手,它利用了MFC的AfxBeginThread函数启动一系列帮助线程。每一个帮助线程要末挪用CoInitialize要末挪用AfxOleInit(MFC中相似CoInitialize的函数)来初始化COM。某些帮助线程则挪用CoCreateInstance来创立COM对象,并将所前往的接口指针封送到其他帮助线程。从创立这些对象的线程中挪用对象将十分顺遂,但从其他线程的挪用却从不前往。您晓得这是为何吗?
假如您以为成绩与动静轮回(或短少动静轮回)相干,那末谜底完整准确。现实的确云云。当一个线程挪用CoInitialize或AfxOleInit时,它是放在单线程单位(STA)中。当COM创立一个STA时,它会创立一个随附的埋没窗口。以STA中的对象为方针的办法挪用将转换为动静,并放进与该STA联系关系的窗口的动静行列中。当运转在该STA中的线程检索到代表办法挪用的动静时,埋没窗口的窗口历程就会将动静转换回办法挪用。COM利用STA实行挪用序列化。STA中的对象一次不成能吸收一个以上的挪用,由于每一个挪用都要传送给一个并且是唯一一个运转在对象单位中的线程。
假如基于STA的线程没法处置动静会怎样呢?假如它没有动静轮回又会怎样呢?针对该STA中对象的单位间办法挪用将不再前往;它们将在动静行列中被永久弃捐。MFC帮助线程中没有动静轮回,因而假如投止在这些STA中的对象要从其他单位的客户端吸收办法挪用,那末MFC帮助线程和STA是共同欠好的。
这个故事的寄意安在呢?STA线程必要动静轮回,除非您一定它们不会包括要从其他线程挪用的对象。动静轮回能够像如许复杂:- MSGmsg;while(GetMessage(&msg,0,0,0))DispatchMessage(&msg);
复制代码 另外一种计划是将COM线程移到MTA中(大概在Windows2000中,移到中立线程单位,即NTA中),这里没有动静行列依附项。
<br>单位模子对象必需回护共享数据
另外一个困扰COM开辟职员的通病是标志为ThreadingModel=Apartment的历程内对象。这项指定告知COM,对象的实例必需只能在STA中创立。它还可以让COM自在地将这些对象实例放在任何主机历程的STA中。
假定客户端使用程序有五个STA线程,每一个线程都利用CoCreateInstance来创立统一个对象的一个实例。假如线程是基于STA的,且对象标志为ThreadingModel=Apartment,则这五个对象实例将在对象创立者的STA中创立。由于每一个对象实例都在占用其STA的线程上运转,因而一切五个对象实例都能够并交运行。
到今朝为止,统统优秀。如今思索一下,假如这些对象实例共享数据会产生甚么情形。由于对象都在并发线程上实行,两个或更多的对象大概会同时实验会见统一个数据。除非一切这些会见都是读取会见,不然就会变成劫难。成绩大概不会很快展现出来;它们会以和工夫严密相干的毛病情势呈现,因而很难诊断和重现。这就注释了以下现实的缘故原由:ThreadingModel=Apartment对象应当包含可同步对共享数据的会见的代码,除非您可以断定对象的客户端不会对实行会见的办法举行堆叠挪用。
成绩在于,太多的COM开辟职员信任ThreadingModel=Apartment可以使他们免于编写线程平安的代码。现实并不是云云—最少不完整云云。ThreadingModel=Apartment其实不意味着对象必需是完整线程平安的,它代表的是一个对COM的答应,即会见两个或更多对象实例共享的数据(或此对象和其他对象的实例共享的数据)时是以线程平安的体例举行的。而供应该线程平安性的义务应当由您,即对象完成者来卖力。共享数据的范例和巨细多种多样,但年夜多是以全局变量、C++类中的静态成员变量和函数中声明的静态变量的情势呈现。即便是以下如许有害的语句也会在STA中出成绩:- staticintnCallCount=0;nCallCount++;
复制代码 由于这个对象的一切实例都将共享一个nCallCount实例,编写这些语句的准确体例以下:- staticintnCallCount=0;InterlockIncrement(&nCallCount);
复制代码 注重:您可使用临界区、互锁函数或您但愿的任何体例,但不要忘了会见基于STA的对象共享的数据时要举行同步化!
<br>审慎启动用户
这里另有一个成绩让很多COM开辟职员都吃过甜头。客岁春季,有一家公司向我告急呼救,他们的开辟职员利用COM构建了一个散布式使用程序,个中客户端历程运转在与远程服务器的Singleton对象相毗连的收集事情站上。在测试过程当中,他们碰到了一些十分奇异的举动。在一种测试场景中,客户端对CoCreateInstanceEx的挪用可以使它们与Singleton对象一般毗连。而在另外一个场景中,对CoCreateInstanceEx的不异挪用发生了多个对象实例和多个服务器历程,使客户端没法与统一个对象 实例毗连,从而实践影响了使用程序。在这两个场景中,硬件和软件是完整不异的。
此成绩仿佛与平安有关。当处置远程激活哀求的COM服务把持办理器(SCM)在另外一台呆板上启动一个历程时,它会为该历程分派一个标识。除非别的指定,它选择的标识就是启动用户的标识。换句话说,分派给服务器历程的标识与启动它的客户端历程的标知趣同。在这类情形下,假如Bob登录呆板A,并利用CoCreateInstanceEx毗连呆板B上的Singleton对象,而Alice也在呆板C上依样画葫芦,就会启动两个分歧的服务器历程(最少在两台分歧的WinStation上),实践上使客户端没法再用Singleton语义与共享的对象实例毗连。
两个测试场景之以是会发生天差地别的了局,其缘故原由就是在一个场景(谁人能够事情的场景)中,一切测试职员都利用只为测试而设置的一个特别帐户以统一团体的身份登录。而在另外一个场景中,测试职员都利用他们的一般用户帐户登录。当两个或更多的客户端历程具有不异标识时,它们能够乐成毗连到设置为假定启动用户标识的服务器历程。可是,假如客户端有分歧的标识,SCM会利用多个服务器历程(每一个独一客户端标识一个)分开分派给分歧对象实例的标识。
<br>
DCOMCNFG中的用户帐户
找到成绩今后,办理起来就很复杂了:设置COM服务器,让其利用特定的用户帐户而不是假定启动用户的标识。完成这一义务的一种体例是在服务器呆板上运转DCOMCNFG(Microsoft的DCOM设置工具),并将“launchinguser”变动为“Thisuser”(请拜见)。假如您喜好经由过程编程体例举行变动(大概从安装程序动手),请在主机注册表的HKEY_CLASSES_ROOTAppID部分的COM服务器项中增加RunAs值(请拜见)。
<br>
增加RunAs值到注册表中
您还必要利用LsaStorePrivateData将RunAs帐户的暗码存储为LSA密钥,并利用LsaAddAccountRights确保帐户具有“Logonasbatchjob”的权限。(有关详细操纵的示例,请拜见PlatformSDK中的DCOMPERM示例。请出格注重名为SetRunAsPassword和SetAccountRights的函数。)
<br>DCOM不适于防火墙
关于DCOM特征和功效的一个罕见成绩是:“它能跨Internet事情吗?”DCOM可以很好地跨Internet事情,只需将它设置为利用TCP大概UDP,而且经由过程授与任何人启动和会见权限,可将服务器设置为同意匿名办法挪用。究竟,Internet是一个伟大的IP收集。但冲突的是,假如您将一个现有的DCOM使用程序(在公司的外部收集或intranet中事情得很好)改成跨Internet事情,它很有大概失利得很惨。多是甚么缘故原由呢?防火墙。
DCOM生来与防火墙的干系就如油与水的干系。缘故原由之一是COM的SCM利用端口135与其他呆板上的SCM通讯。防火墙限定了它可使用的端口和协定,大概会回绝经由过程端口135传进的通讯量。但更年夜的成绩在于,为了不与利用套接字、管道和其他IPC机制的使用程序抵触,DCOM没有流动利用特定局限的端口,相反,它在运转时才选择所利用的端口。默许情形下,它可使用从1,024到65,535局限内的任何端口。
同意DCOM使用程序经由过程防火墙的一种体例是,为DCOM要利用的协定翻开端口135和端口1,024-65,535。(默许情形下,WindowsNT4.0是UDP协定,Windows2000是TCP协定。)可是,这比移除一切防火墙好不了几。对此,您公司的IT职员大概要宣布定见了。
另外一种更平安和更实际的办理计划是,限定DCOM利用的端口局限,并只为DCOM通讯量翻开一组小局限端口。依据理论准绳,您应当为每一个服务器历程分派一个端口,将毗连导出到远程COM客户端(不是每一个接口指针一个端口或每一个对象一个端口,而是每一个服务器历程一个)。将DCOM设置为利用TCP而不是UDP是一个好办法,出格是在服务器对其客户端实行回调时。
DCOM用于远程毗连的端口局限和所用的协定可经由过程注册表举行设置。在Windows2000和WindowsNT4.0ServicePack4或更高版本上,您能够用DCOMCNFG使用这些设置变动。以下是将DCOM设置为经由过程防火墙事情的举措。
<br>
选择协定
- 在服务器(在防火墙后存放远程对象的呆板)上,将DCOM设置为利用TCP作为其所选协定,如中所示。
- 在服务器上,限定DCOM将利用的端口局限。记着为每一个服务器历程最少分派一个端口。中的示例将DCOM限定为端口8,192到8,195。
- 翻开您在步骤2当选择的端口,使TCP通讯量可以经由过程防火墙。同时翻开端口135。
<br>
选择端口
实行这些步骤,DCOM就能够很好地跨防火墙事情了。假如您乐意,SP4和更高版本还可以让您为独自的COM服务器指定闭幕点。更多信息,请浏览MichaelNelson关于DCOM和防火墙的优异论文,该论文可在MSDNOnline站点上找到(请拜见http://msdn.microsoft.com/library/en-us/dndcom/html/msdn_dcomfirewall.asp)。
还应注重的是,经由过程在服务器上安装Internet信息服务(IIS),并利用COMInternet服务(CIS)经由过程端口80路由DCOM通讯量,SP4和更高版本的用户还可使用CIS来供应与防火墙兼容的DCOM。有关该主题的更多信息,请参阅http://msdn.microsoft.com/library/en-us/dndcom/html/cis.asp。
<br>利用线程或异步伐用来制止DCOM超时设定太长
老是有人问我当DCOM没法完成远程实例化哀求或办法挪用时呈现的超时设定太长的成绩。典范的场景以下:客户端挪用CoCreateInstanceEx来实例化远程呆板上的一个对象,可是这台呆板一时离线了。在WindowsNT4.0上,激活哀求不会当即失利,DCOM大概会花上一分钟或更长工夫来前往失利的HRESULT。DCOM还大概消费很长工夫,使指向已不再存在或其主机已离线的远程对象的办法挪用失利。假如大概,开辟职员应当怎样制止这些较长的超时设定呢?
要回覆这个成绩,几句话是讲不分明的。DCOM高度依附于基本收集协定和RPC子体系。并没有甚么奇妙的设置可以让您限定DCOM超时设定的延续工夫。可是,我常常利用两种技能来制止较长超时设定的负感化。
在Windows2000中,当挪用在COM信道中挂起时,您可使用异步办法挪用来开释挪用线程。(有关异步办法挪用的先容,请参MSDNMagazine2000年4月刊的“Windows2000:AsynchronousMethodCallsEliminatetheWaitforCOMClientsandServersAlike”。假如异步伐用在公道工夫内没有前往,您能够经由过程挪用用于初始化挪用的挪用对象上的ICancelMethodCalls::Cancel来作废它。
WindowsNT4.0不撑持异步办法挪用,乃至在Windows2000中也不撑持异步激活哀求。怎样办理呢?从背景线程挪用远程对象(或是实例化该对象的哀求)。使主线程在事务对象上堵塞,并指定超时设定值以反应您乐意守候的工夫长度。当挪用前往时,让背景线程来设置事务。假定主线程利用WaitForSingleObject堵塞,当WaitForSingleObject前往时,前往值能够告知您,前往是由于办法挪用或激活哀求前往,仍是由于您在WaitForSingleObject挪用中指定的超时设定到期。您不克不及在WindowsNT4.0中作废挂起挪用,可是最少主线程能够自在地实行本人的义务。
上面的代码演示了基于WindowsNT4.0的客户端怎样才干从背景线程挪用对象。- ////////////////////////////////////////////////////////PlacingaMethodCallfromaBackgroundThread///////////////////////////////////////////////////// HANDLEg_hEvent;IStream*g_pStream;//ThreadAg_hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);CoMarshalInterThreadInterfaceInStream(IID_IFoo,pFoo,&g_pStream);DWORDdwThreadID;CreateThread(NULL,0,ThreadFunc,NULL,0,&dwThreadID);DWORDdw=WaitForSingleObject(g_hEvent,5000);if(dw==WAIT_TIMEOUT){//Calltimedout}else{//Callcompleted}...//ThreadBIFoo*pFoo;CoGetInterfaceAndReleaseStream(g_pStream,IID_IFoo,(void**)&pFoo);pFoo->Bar();//Makethecall!SetEvent(g_hEvent);CloseHandle(g_hEvent);
复制代码 在此示例中,线程A封送了一个IFoo接口指针,并启动线程B。线程B作废封送了该接口指针,并挪用IFoo::Bar。不管挪用前往所消费的工夫有多长,线程A都不会堵塞凌驾5秒钟,由于它在WaitForSingleObject的第二个参数中传送的是5,000(单元为微秒)。这并非太好的举措,可是假如“不管在线路的另外一端产生甚么情形,线程A都不会挂起”这一点很主要的话,忍耐这类贫苦也算值得。
<br>共享对象其实不简单
从我收到的邮件和在集会上被问到的成绩判别,困扰很多COM程序员的一个成绩是怎样将两个或更多的客户端与一个对象实例毗连。要回覆这个成绩,写出长篇年夜论(或是一本小册子)都很简单,但实在只需申明与现有对象的毗连既不简单也不主动化,就充足了。COM供应了大批创立对象的体例,包含很受接待的CoCreateInstance(Ex)函数。可是COM缺少一种通用的定名服务,同意利用称号或GUID来标识对象实例。并且它没有供应内置的体例来创立对象,然后将它标识为挪用的方针以检索接口指针。
这是否是意味着将多个客户端与单一对象实例毗连就不成能了呢?固然不是。完成这一点有五种体例。在这些资本链接中,您能够找到更多信息乃至是示例代码,来引导您的操纵。请注重,这些手艺从一样平常意义上讲不克不及交换;一般,情况要素会决意哪一种体例(假如有)合用于手边的义务:Singleton对象Singleton对象就是只实例化一次的对象。大概会有10个客户端挪用CoCreateInstance来“创立”Singleton对象,但实践上,它们都是吸收指向统一对象的接口指针。ATLCOM类可经由过程在其类的 声明中增加DECLARE_CLASSFACTORY_SINGLETON语句,来转换为Singleton。
文件名字对象假如一个对象完成了IpersistFile,并在运转中对象表(ROT)中利用文件名字对象(它封装了传送给对象的IPersistFile::Load办法的文件称号)注册了本人,那末客户端就能够利用文件名字对象毗连对象的现有实例了。实践上,文件名字对象同意利用文件称号来定名对象实例,对象可在这些文件称号中存储它们的耐久性数据。它们乃至可以跨呆板事情。
CoMarshalInterface和CoUnmarshalInterface保留接口指针的COM客户端能够与其他客户端共享这些接口指针,只需它们乐意封送指针。COM为乐意将接口指针封送给统一历程中其他线程的线程供应了优化(请拜见教导2),可是假如客户端线程属于其他历程,CoMarshalInterface和CoUnmarshalInterface就是完成接口共享的关头路子了。有关会商和示例代码,请参阅MSJ1999年8月刊中我的超酷代码专栏。
自界说类对象一切“能够在内部创立的”COM对象都陪伴有自力对象,称为类对象,它们的感化是创立所谓COM对象的实例。年夜多半类对象都要完成一个名为IClassFactory的接口,个中包含一个能够创立对象实例的名为CreateInstance的办法。(在底层,COM将CoCreateInstance(Ex)挪用转换为对IClassFactory::CreateInstance的挪用)。IClassFactory的成绩在于,在检索指向之前创立的对象实例的接口指针时,它一点用途都没有。自界说类对象是完成替换IClassFactory的自界说激活接口的类对象。因为界说了接口,您还能够界说办法来检索对已由该类对象创立的对象的援用。更多信息和以ATL编写的示例,请参阅1999年2月的超酷代码专栏。
自界说名字对象1999年11月的超酷代码专栏先容了同意利用C款式字符串定名对象实例的自界说名字对象类。将一个实例称号传送给MkParseDisplayName,您就取得了一个与对象实例毗连的名字对象。这些范例的名字对象的一个弱点是,它们在WindowsNT4.0中不克不及跨呆板事情。
在利用这些办法中的任一个在客户端之间共享对象实例之前,叨教本人一个成绩:共享是必须的吗?假如办法挪用从一个内部数据源(数据库、硬件设备,乃至多是全局变量)检索数据以呼应客户真个哀求,那末为何不为每一个客户端分派一个对象实例,并同意每一个实例会见数据源呢?您大概必需同步化对数据源的会见,但纷歧定要利用自界说类对象、自界说名字对象等手腕。这就是用Microsoft事件服务(MTS)构建的使用程序的事情体例,从各类来由来看,它已证实是一种有目共睹的编程模子,而不单单是完成上的烦琐和功能的改良。
<br>与我接洽
您有甚么坚苦的Win32、MFC、MTS或COM(+)编程成绩必要解答吗?假如有,请给我发邮件,地点是jeffpro@msn.com。请在邮件主题中加上“WickedCode”(超酷代码)字样。请包涵工夫不同意我一般回覆这些成绩,可是关于每一个成绩,我城市思索到场到将来的专栏内容中。
JeffProsise是ProgrammingWindowswithMFC(MicrosoftPress,1999年)一书的作者。他仍是Wintellect(一家软件征询和教导公司)的兴办人之一,该公司的网址是http://www.wintellect.com。
摘自MSDNMagazine的2000年11月刊。此杂志可经由过程各地的报摊购置,也能够定阅。
本文由VCKBASEMTT翻译
翻译后文章:http://www.vckbase.com/document/viewdoc/?id=1183#STA%20线程必要动静轮回
本文转载自微软中国社区:http://www.microsoft.com/china/MSDN/library/windev/COMponentdev/CDwickedtoc.mspx
公布日期:5/20/2004
更新日期:5/20/2004
原文出处:WickedCode:EightLessonsfromtheCOMSchoolofHardKnocks(JeffProsise)
进而能拉拢大多数程序员用windows产品。并且从net网页编程网页编程AJAX可以跨平台这一点上,间接证明了我们的推断,至少证明了微软做过这方面的研究。所以如果哪一天突然听说了.net网页编程可以跨平台了,那么请不要吃惊,如果这一天真的到来,java就到了真正和.net网页编程决战的时刻。因为不到万不得以的时候微软是不会推出跨平台的.net网页编程的,如果跨平台的.net网页编程还不足以对抗java的话,那么微软还剩的手段就是开源了,呵呵。 |
|