C/C++源代码的Include依赖关系图

前一篇博文中我曾仔细介绍过如何查看C/C++代码的依赖项关系图,在这篇文章中我将会介绍如何使用Visualization and Modeling Feature Pack 工具包,查看C/C++源代码的Include关系图,这个功能是针对C/C++编程语言本身的特性而新加入的。在这里我依然会使用工程Hilo 作为案例,展示如何以图形化的方式显示工程中源代码文件与头文件之间Include关系。 首先,在Visual Studio下打开工程Hilo,在菜单栏中选择菜单“体系结构->生成依赖关系图->By Include File” 第一次操作时,有时我们将会发现一个名为“Analyzing Files”的进度框会跳出,提示用户“代码正在解析中”,如图: 稍等片刻后,如下的DGML有向图将会生成,这张图除了展示工程Browser和Common内部源文件与头文件的Include关系外,还显示了工程之间,工程与外部头文件的Include引用关系。 下面我将会使用自顶向下的方式给您解释如何去阅读和分析这张图。点击该图右键菜单”分组->全部折叠”,我们将会得到下图: 这张图很清晰地告诉我们在当前解决方案中包含2个C++工程,分别是Browser和Common。Browser中包含61个源文件/头文件,而 Common中源文件/头文件的数量是29。工程Browser中的源文件Include了工程Common和”外部”中的头文件,而工程Common仅仅Include了“外部”中的头文件。这里的browser.vcxproj和common.vcxproj比较容易理解,分别包含了这两个工程中所有的源文件和头文件,而在”外部”这个结点中,则包括了所有被工程Browser和common所Include,但不属于这两个项目的头文件.让我们展开”外部”节点, 我们发现其中包含2个名为“Windows SDK”和”C/C++Standard Library”的子节点,如图: 为了区分不同库的头文件,我们根据头文件所属领域的不同,我们将外部引用的头文件分为两类:“Windows SDK”和“C/C++ Standard Library”。节点“Windows SDK”下包含存储路径在“%WindowsSdkDir%\include”下的头文件,而节点“C/C++ Library”下的头文件的存储路径为“%VSINSTALLDIR%\vc\include”。在这里,工程Browser和Common Include的总共引用了“Window SDK”的13个头文件,工程Browser和Common,以及“Windows SDK”库引用了“C/C++ Standard Library”的 12个头文件。 从上面的图中,我们可以了解到整个解决方案的Include依赖关系图的结构。然而,这个图中有如此多的节点,我们如何来查看我们想要了解的某一个或一些文件的Include依赖关系呢?首先,我们可以通过Ctrl+F来找到我们想要找到的文件。按下Ctrl+F,然后输入 “carouselpane.h”, Visual Studio将自动帮我们定位到所在的节点(如下图),同时与该链接相连的所有链接将会被高亮,链接箭头方向代表Include关系,如图: 源文件“carouselpane.cpp”include了头文件”carouselpane.h”,在图中将会有条始于节点 “carouselpane.cpp”,终于节点“carouselpane.h”的有向链接。停留鼠标在该链接上,显示“导向按钮”,点击“导向按钮” 中的“+”,我们将会被带到源代码文件”CarouselPane.cpp” 在源代码文件”carouselpane.cpp”中,代码行#include “CarouselPane.h”被自动选中,这个操作诠释了源文件“carouselpane.cpp”与“carouselpane.h”的 Include关系。点击右键菜单“查看内容”,头文件“carouselpane.h”将会被打开, 在打开的头文件“carouselPane.h”中,点击右键菜单“Generate Graph of Include Files”,一张关于头文件carouselPane.h Include”和Include By的依赖图将会产生,如下图: 该图所表达的语义是工程Browser下“Carouselpane.h”头文件被3个.cpp文件Include的,并且该文件Include了 8个.h文件。 这样,通过这样的子图,我们就能够比较方便地看到某个文件的Include和Include By依赖关系图了。 总结: “Include”依赖图提供了一种以图形化方式显示源文件与头文件间“Include”关系的方式,基于解决方案生成的“Include”图可以帮我们理解工程间以及工程与库头文件的“Include”关系,而基于单个文件的“Include”图可以帮我们进一步理解单个文件的“Include”和…

0

C/C++代码可视化

今年4月发布的Visual Studio 2010 (以下简称VS2010)的旗舰版 提供了多种构架工具,来帮助开发人员分析和理解已有的代码库(Legacy Codebase),这些工具包括:依赖项关系图、顺序图以及体系结构资源管理器,Jennifer Marsman在她的博客中详细介绍了如何使用这些工具。然而在VS2010的正式发布版中,这些工具仅支持对.NET语言工程的支持,更确切地讲是仅支持C# 和VB.NET工程。对于广大的C/C++开发人员来说,他们也非常希望能够拥有类似的功能。为此,Visual Studio团队在今年6月份发布的Visualization and Modeling Feature Pack 工具包中,实现了对C/C++代码的可视化功能。 在安装了这个工具包后,就可以通过创建依赖项关系图(Dependency Graph)来了解和分析已有的C/C++代码工程了。这里我们以VS C++团队编写的Hilo工程 为例,来展示一下如何为C++ 工程创建依赖项关系图,Hilo的源代码可以在http://code.msdn.microsoft.com/Hilo下载到。 在VS中打开Hilo工程,选择菜单“体系结构”->“生成依赖项关系图”,如下图所示。在子菜单中,“按程序集”、“按名字空间”和“按类和自定义”是在VS 2010发布版中就有的,它们也可以用于C/C++的工程。这里新增加的一个菜单项是 “By Include File”,它是用来生成C/C++文件之间的#include引用关系的,会在另外的博客中进行介绍。注意:Visualization and Modeling Feature Pack仅提供了英文版,它可以安装在其它语言版本的VS 2010上,但显示的内容仍是英文的。 这里选择“按程序集”菜单项,它会生成如下的依赖项关系图(DGML有向图),显示Browser.exe与其它外部动态库文件之间的总体依赖关系: 进一步展开“外部”模块,可以看到Browser.exe依赖到了那些具体的动态库文件,如下图所示。当鼠标停留在模块之间的有向连线上的时候,会显示出“导向按钮”以及对连线所代表依赖关系的描述信息。 一步步展开到最底层,展现出来的就是函数之间的调用关系,如下图所示, Hilo::AnimationHelpers名字空间与Ole32.dll的以来关系归根结底就是 AnimationUtility::Initilize对CoCreateInstance的调用关系。鼠标双击图中的函数,如果有对应的代码则会自动打开代码文件,并自动定位到函数的位置,这样大大方便用户在浏览依赖关系模型时察看其对应的代码内容。 这个版本的Visualization and Modeling Feature Pack所生成的C/C++工程依赖项图,相对于为C#和VB.NET生成的依赖图,还是有一定的局限性: 首先,它只显示了函数调用类型的依赖关系,而并没用有像C#/VB.NET生成的依赖项关系图那样,还包含有引用、继承等等多种依赖关系; 其次,只显示了跨二进制文件(Cross-binary)之间的依赖关系,而没有同一文件内部(Intra-binary)函数之间的调用关系; 最后,只有参与了依赖关系的文件、名字空间、类和函数才被显在图上,而其它内容则没有显出来。这就解释了为什么在Ole32.dll中列出了4个函数,而其它的很多函数没有被列出,因为它们在当前的工程中没有被调用; 参考资源: Jason的博客:Announcing: VS2010 Productivity Power Tools and Modeling Feature Packs Soma的博客:Modeling Websites and…

0

针对C/C++代码的工程间依赖关系的层验证

在前面一篇blog中我提到过,最近我们团队刚刚发布了针对Visual Studio 2010的一个功能扩展包:Visualization and Modeling Feature Pack , 其中包含的一个非常cool的功能就是基于C/C++代码的工程间依赖关系的层验证,为广大的C++程序员带来了福音。 层验证是Visual Studio 2010中一个非常有用的功能,在项目的设计阶段,架构师可以借助层图创建Class/Namespace/Method/Project之间的依赖约束关系,在开发阶段中,频繁的代码验证可以帮助项目团队尽快地发现实现与设计的偏离,最终协助 项目团队开发出与设计一致的项目工程。我这篇blog主要侧重于针对C/C++项目的层验证,若对层验证不熟悉的读者,可以参考文章使用VSTS 2010进行层验证 ,里边将会手把手教您怎么创建建模工程,层图以及如何做层验证。 目前我们所支持依赖关系验证仅仅是针对生成目标为.DLL/.EXE的工程间静态调用,静态调用是针对动态调用而言的,是动态链接库调用的一种方式,调用时是由编译系统完成对DLL的加载(Load)和应用程序结束时DLL的卸载(Free)的代码注入。下面我将会通过一个简单案例来介绍如何使用 Visualization and Modeling Feature Pack中C/C++代码的工程之间依赖关系的层验证来帮助项目团队开发出与设计一致的项目工程。案例开始啦。。。 用户需求: 根据源代码结构,绘制一张程序元素Namespace和Class之间包含关系的图。针对目标编程语言可以是C++,C#,和JAVA。 设计: 为了支持将来出现的新型编程语言,增加项目的可扩展性和可维护性。在这里我们将项目实现抽象为3个工程: Data Provider:解析源代码文件,设别源代码中的程序结构和元素。 Data Format:接受Data Provider产生的数据源,使用XML文件存储Namespace和Class之间的包含关系。 Draw Diagram:以图形化方式显示DataFormat层所产生的xml文件。 根据以上的设计思想,首先创建解决方案ElementPresenter,然后添加建模工程(ModelingProject) ElementPresenter,并在该建模工程下添加如下的层图来表示项目中将会包含的各个工程以及工程之间调用关系的约束。 这个层图规定工程DrawDiagram可以调用工程DataFormat中提供的API,工程DataFormat可以调用 DataProvider提供的API,但是DrawDiagram不能跨越工程DataFormat直接使用DataProvider提供的API。 实现: 在解决方案ElementPresenter下添加动态链接库工程DataProvider,其生成的目标动态链接库的导出元素有函数ReadElements和类SourceElements,如下所示: #ifdef DATAPROVIDER_EXPORTS #define DATAPROVIDER_API __declspec(dllexport) #else #define DATAPROVIDER_API __declspec(dllimport) #endif class DATAPROVIDER_API SourceElements { }; SourceElements DATAPROVIDER_API…

0

MSDN已提供下载Visualization and Modeling Feature Pack

经过半年多的努力,我们参与开发的Visualization and Modeling Feature Pack已经在MSDN上发布以供下载。详情请看这里 。暂时我们只提供英文版本。在这个Feature Pack中,对于c++增加了更多的支持,比如可以针对c++程序生成依赖关系图,还能进行层验证等等。我们将在接下来的篇幅中介绍这些功能,敬请等待!

0

ALM for C++中文博客正式开通啦

大家好。我们是微软亚太研发集团服务器与开发工具事业部位于上海的开发团队,主要负责Microsoft Visual Studio中对于C++应用程序的生命周期管理。我们想在这里,通过博客的方式给大家介绍如何在Microsoft Visual Studio中对C++应用程序的整个开发周期进行管理。内容将包括Microsoft Visual Studio中已有的部分,也将包括我们最近开发的插件中的功能,等等。这个博客面向本地客户,将会使用中文来介绍我们的产品。这里是我们的英文博客,两边会同步更新。 若您有任何问题和建议,可以在博客中留言或发短消息,中英文皆可。这样能够帮助我们更快得到您的反馈,以便我们改进产品。谢谢! 若希望了解更多关于微软服务器与开发事业部(中国),请察看这里:服务世界 开发未来

0