`
coolerbaosi
  • 浏览: 727177 次
文章分类
社区版块
存档分类
最新评论

《COM技术内幕》读书笔记——第10章 EXE中的服务器 代码调试

阅读更多

也许是进度太快,前面的章节没有很好的把握,我在读第10章的内容的时候,感觉有很多知识点还没有清楚,而且这章结构组织没之前的清楚,甚至可以说有点混乱。再次回顾可以加深之前内容的掌握,在这里有一个关键的点就是——完完整整的把课本的代码走一遍,理解怎么写为什么写这些代码。

对于本章的代码,也是老问题了,此书作者可没有花时间在讲解代码调试上。由于年代久远,按书上说的nmake -f makefile会发现出现很多错误,花了好一些时间调整好可以编译调试。现在把一些调试本章代码的体会写下来。

这些老代码,一般是使用nmake命令来编译,我们在新的VS环境下可以导入到VS环境中更好的跟踪代码,理解COM的精粹。但说回来,对编译过程没有足够的了解或经验有些欠缺,不容易修改好。

本章的标题是:EXE中的服务器。一种是同一进程中扮演服务器的角色,另一种是不同进程中扮演服务器角色。

进入原始代码目录Chap10中找到makefile——如果不懂makefile是什么?呃,那就要先学makefile了。

always:
	nmake -f make-one
	nmake -f make-one OUTPROC=1

可以看出,就是执行了这两个命令,打开make-one的文件,找到all标签:

all : Client.exe $(TARGETS)

再找到Client.exe的编译依赖

Client.exe : Client.obj Guids.obj Util.obj
	link $(EXE_LINK_FLAGS) Client.obj Guids.obj Util.obj   \
		libcmtd.lib libcimtd.lib $(LIBS) 

Guids.obj?代码里没有这个文件,怎么办?再看书,这是IDL搞的鬼!需要用MIDL工具生成这东西!为什么?看书去!在make-one文件里有这么一行:

midl /h iface.h /iid guids.c /proxy proxy.c server.idl

没错,就是它!使用server.idl文件生成一个头文件和两个c文件。

好了,这里是Client.exe的内容,还记得有个&(TARGETS)吧?现在在看看这东西怎么编译:

!IF "$(OUTPROC)" == ""
!MESSAGE Building in-proc server.
SERVER =
TARGETS = Server.dll
DIR_SERVER = InProc
!ELSE
!MESSAGE Building local/remote server.
SERVER=/D_OUTPROC_SERVER_
TARGETS = Server.exe Proxy.dll
DIR_SERVER = OutProc
!ENDIF 

回想makefile里面第二条编译指令带着OUTPROC=1这个参数,第一个是不带的。并且可以找到这样的说明Use OUTPROC=1 to build out-of-proc version. 结合书本上讲的内容,这就明白了,不带OUTPROC=1参数的是进程内服务,带的是进程间服务。先来搞进程内服务的,也就是生成Server.dll。找到其编译依赖:

SERVER_OBJS = $(DIR_SERVER)\Server.obj     \
              $(DIR_SERVER)\Cmpnt1.obj     \
              $(DIR_SERVER)\Cmpnt2.obj     \
              $(DIR_SERVER)\Cmpnt3.obj     \
              $(DIR_SERVER)\Registry.obj   \
              $(DIR_SERVER)\Cfactory.obj   \
              $(DIR_SERVER)\Cunknown.obj   \
              $(DIR_SERVER)\Util.obj       \
              Guids.obj	

!IF "$(OUTPROC)" == ""
Server.dll:  $(SERVER_OBJS) Server.def 
	link $(DLL_LINK_FLAGS) $(SERVER_OBJS) libcmtd.lib   \
		libcimtd.lib $(LIBS) /DEF:Server.def 
	regsvr32 -s Server.dll

很清楚,需要哪些obj,再跟到obj的依赖上,可以列出全部需要的文件集合。

$(DIR_SERVER)\server.obj : server.cpp cunknown.h cfactory.h iface.h
	cl $(CPP_FLAGS)  /Fo"$*.obj" server.cpp

$(DIR_SERVER)\cmpnt1.obj : cmpnt1.cpp cmpnt1.h iface.h registry.h   \
		CUnknown.h
	cl $(CPP_FLAGS) /Fo"$*.obj" cmpnt1.cpp

$(DIR_SERVER)\cmpnt2.obj : cmpnt2.cpp cmpnt2.h iface.h registry.h   \
		CUnknown.h
	cl $(CPP_FLAGS) /Fo"$*.obj" cmpnt2.cpp

$(DIR_SERVER)\cmpnt3.obj : cmpnt3.cpp cmpnt3.h iface.h registry.h   \
		CUnknown.h
	cl $(CPP_FLAGS) /Fo"$*.obj" cmpnt3.cpp

$(DIR_SERVER)\CUnknown.obj : CUnknown.cpp CUnknown.h
	cl $(CPP_FLAGS) $(SERVER) /Fo"$*.obj" CUnknown.cpp

$(DIR_SERVER)\CFactory.obj : CFactory.cpp CFactory.h
	cl $(CPP_FLAGS) $(SERVER) /Fo"$*.obj" CFactory.cpp

$(DIR_SERVER)\registry.obj : registry.cpp registry.h
	cl $(CPP_FLAGS) $(SERVER) /Fo"$*.obj" registry.cpp

# util.cpp compiled for server.
$(DIR_SERVER)\util.obj : util.cpp util.h
	cl $(CPP_FLAGS) $(SERVER) /Fo"$*.obj" util.cpp 


好了,现在基本的工程逻辑弄清楚了,需要两个工程:Client.exe工程,server.dll是服务组件的工程(需要注册后才能使用,怎样注册是很早章节的事情了)。中间用到的iface.h guids.c proxy.c是用IDL文件生成的,需要在VS工程编译之前完成(当然也可以在工程中加入IDL文件,设置生成的文件名称)。

我就是按上面的步骤做,把工程建立起来调试理解当中的代码的。当中大部分使用char的情况我都改成TCHAR来运行。把我建立的工程上传到资源中,希望帮助到和我一样学习COM技术的朋友。

另外,上面没有提到进程外服务组件的工程编译,其实也是相同的道理。关键是从makefile入手,结合书上的内容理解编译步骤(前提当然是书上的内容是正确的),然后弄清楚建立几个工程,需要哪些资源和文件,运行的时候注意什么内容。


$(DIR_SERVER)\server.obj : server.cpp cunknown.h cfactory.h iface.h
	cl $(CPP_FLAGS)  /Fo"$*.obj" server.cpp

$(DIR_SERVER)\cmpnt1.obj : cmpnt1.cpp cmpnt1.h iface.h registry.h   \
		CUnknown.h
	cl $(CPP_FLAGS) /Fo"$*.obj" cmpnt1.cpp

$(DIR_SERVER)\cmpnt2.obj : cmpnt2.cpp cmpnt2.h iface.h registry.h   \
		CUnknown.h
	cl $(CPP_FLAGS) /Fo"$*.obj" cmpnt2.cpp

$(DIR_SERVER)\cmpnt3.obj : cmpnt3.cpp cmpnt3.h iface.h registry.h   \
		CUnknown.h
	cl $(CPP_FLAGS) /Fo"$*.obj" cmpnt3.cpp

$(DIR_SERVER)\CUnknown.obj : CUnknown.cpp CUnknown.h
	cl $(CPP_FLAGS) $(SERVER) /Fo"$*.obj" CUnknown.cpp

$(DIR_SERVER)\CFactory.obj : CFactory.cpp CFactory.h
	cl $(CPP_FLAGS) $(SERVER) /Fo"$*.obj" CFactory.cpp

$(DIR_SERVER)\registry.obj : registry.cpp registry.h
	cl $(CPP_FLAGS) $(SERVER) /Fo"$*.obj" registry.cpp

# util.cpp compiled for server.
$(DIR_SERVER)\util.obj : util.cpp util.h
	cl $(CPP_FLAGS) $(SERVER) /Fo"$*.obj" util.cpp 




http://download.csdn.net/detail/eagleatustb/4972005

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics