您现在的位置是:首页微电子应用论文

MFC技术在Vega应用程序开发中的应用探析

发布时间:2011-02-23 16:51:50更新时间:2023-06-02 16:30:24 1

摘要:简要介绍Vega应用程序的基本框架;重点分析基于MFC的Vega应用程序的基本框架和开发中所遇到的两个线程问题,并提供相应的解决方法。 论文网,期刊发表网,职称论文发表
  关键词:仿真;MFC;线程;Vega
  1Vega应用程序基本框架
  1.1Vega应用程序开发模式简介
  Vega是一种用于实时仿真及虚拟现实应用的高性能软件环境和工具,主要包括两个部分:一个是被称为LynX的图形用户界面的工具箱,另一个则是基于C语言的Vega函数库。LynX的主要功能是通过可视化操作建立起三维场景模型,并将其保存在一个应用定义文件(.ADF)中,而后应用程序就可以通过调用Vega的C语言函数库来对已建好的三维场景进行渲染驱动。
  1.2Vega应用程序基本框架分析
  Vega编程类似于C编程,包括完整的C语言应用程序接口,为软件开发人员提供最大程度的软件控制和灵活性。对于WindowsNT平台上的Vega应用,主要有三种类型:控制台程序、传统的Windows应用程序和基于MFC(MicrosoftFoundationClasses)的应用。但无论是哪一种应用,建立Vega应用程序都需要以下三个步骤:
  第一步,初始化Vega系统并创建共享内存等;
  第二步,通过ADF应用定义文件加载三维模型或是通过显式的函数调用来动态加载三维模型;
  第三步,通过调用配置函数设置完Vega系统后,就开始了Vega应用程序的主循环,主循环的作用是对三维视景进行渲染驱动。它主要分两步,即对于给定的帧速进行帧同步和对当前的显示帧进行必要的处理。
  以下是一个最基本的Vega应用程序框架:
  main(){
  vgInitSys();//初始化
  vgDefineSys(“.adf”文件);//定义
  vgConfigSys();//配置
  while(1){
  vgSyncFrame();//同步帧
  vgFrame();//帧内处理
  //应用程序特定代码}
  这是一个控制台的应用程序。但是Vega只是一个包含十几种不同模块的函数集,并没有窗口函数(虽然Vega函数库中提供了一些窗口和事件管理的函数,但这些函数在实际应用中还远远不够),它缺乏面向对象能力,不符合当前流行的软件设计思想,因此需要一个窗口系统来完成Vega实时仿真的程序设计。而如果在Windows平台上开发,具有良好图形用户界面的应用程序将更受到欢迎。对于基于窗口的应用程序来说,Vega系统通过提供一个窗口初始化函数调用来完成,即只要把上述的初始化函数vgInitSys()替换成vgInitWinSys()即可。该函数通过获得窗口句柄来初始化Vega的显示窗口。Vega窗口和Windows窗口如图1所示。
  2MFC技术在Vega应用程序设计中的应用
  2.1MFC技术与Vega应用程序的接口分析
  鉴于Vega函数是用C++语言编写以及在Windows平台上进行开发,所以就选择了VisualC++这种Windows环境下最好的C++编译器作为开发工具。VisualC++中的MFC类库已是一个相当成熟的类库,特别是其基于文档/视图结构的应用程序框架,已成为开发Windows应用程序的主流框架结构。该框架结构能够将程序中的数据和显示部分进行有效的隔离,并能将一个文档与多个视图进行对应。
  为便于开发出基于MFC的Vega应用程序,Vega通过继承MFC中的CView类而派生出一个子类zsVegaView。这个zsVegaView类提供了启动一个Vega线程最基本的功能,还以虚函数的形式定义了特定的应用程序要进行操作的通用接口,因此用户的应用程序只需从zsVegaView派生出新类并根据需要重载必要的虚函数即可。从设计模式的观点来看,它是采用了模板方法模式(TemplateMethod)。模板方法模式是一种类行为模式,其意图是定义一个操作算法的骨架,而将一些具体步骤延迟到子类中去,这是代码重用的一种基本技术。
  2.2基于MFC的Vega应用程序的线程分析
  通过采用模板方法可以将开发一个基于MFC应用程序的工作量减少到最低,这是Vega系统提供的方法,但由于MFC类库并不是一个支持多线程访问的类库,而派生的子类是通过在OnInitialUpdate()函数中调用基类的runVega()来启动Vega线程,并将派生类的指针作为参数传给新启动的子线程,这恰是问题的所在。由于源代码中的类空间和线程运行时的线程空间是可以相互交迭的,亦即不同的线程在运行时可以访问相同的类的实例(对象),而MFC类库本身设计时并未考虑到多线程访问,因此在线程间传递视图类CView(其子类对象也是一个CView对象)是不安全的。
  2.2.1在Vega线程中更新视图时访问保护异常错误的分析
  错误分析:在单文档多视图中,在Vega线程中改变文档数据后通过调用函数UpdateAllViews()来更新所有相应的视图时立即出现了访问保护异常的错误。这是因为用类CView的派生类来嵌入与Vega功能有关的功能代码对于CView的关联只使用了CView类的视图窗口的句柄,这种设计违反了软件设计的基本准则:高内聚,低耦合。
  解决方法:为了既能保持由模板方法设计带来的好处,又能达到高内聚、低耦合的目标,最好的方法就是进行切割分离,即将所有与Vega系统有关的数据和操作单独作为一个基类CVega来实现,并保持用户的扩展接口,然后只需从CVega类派生出新类并将视图窗口的句柄作为参数进行传递。由于Windows平台采用消息驱动机制,所以当Vega线程改变数据后可以利用视图窗口的句柄发送消息来通知各个视图窗口及时更新。
  2.2.2切换三维场景时地址访问保护错误的分析
  错误分析:Vega应用程序一般通过应用程序定义文件(.ADF)载入三维场景模型,而在实际开发的过程中,当打开应用程序时需要在不退出该应用程序的前提下需要进行三维场景切换,即载入新场景;但是,当Vega线程未退出时重新载入场景会失败,而在切换场景时让正在运行的线程自然终止而重新开启另一个线程则出现了一个地址访问保护的错误。该错误发生在Vega启动时的初始化系统函数vgInitWinSys()执行的过程中,原因是引用了无效的指针。vgInitWinSys()函数的作用主要是初始化Vega系统并创建共享内存等,同时在后台开启了一个Vega窗口子线程,该子线程根据传送的窗口句柄参数创建一个与该句柄对应的Windows窗口相同大小的Vega窗口,并将它覆盖在Windows窗口上,这样Vega系统的渲染窗口就可以嵌入到基于MFC的视图窗口上。该子线程的创建是必需的,但却无法终止它,这是因为它是Vega函数内部创建的,而线程又隶属于进程,只有进程结束了,所有的线程才全部退出。所以,即使创建它的父线程已“死”,它却还“活”着,但因此而保留了一些无用的参数如无效的指针等。而且,当第二个线程启动时函数vgInitWinSys()却不再启动新的子线程而是继续保留原来没“死”的窗口线程,这就导致了地址访问保护的错误。
  解决方法:就是创建一个单独的Vega进程。其设计思想是通过将同一个应用程序中的不同部分进行相互黑箱化,彼此之间仅通过定义好的接口进行访问,这就最大限度地减小各部分之间的相互影响。Windows不是一个实时操作系统,而是一个比较稳定的系统。由于虚拟仿真系统一般都是实时的,在它的视景驱动模块中将处理大量的实时仿真结果数据,所以必须保证该模块中的两个进程之间能快速有效地进行通信。
  在WindowsNT平台上,进程间通信的主要方式有:动态数据交换(DDE)、网络动态数据交换(NetDDE)、Windows套接字(WindowsSockets)、命名管道(NamedPipes)、内存映射文件(Memory-MappedFiles)、NetBIOS、远程过程调用(RPC)以及磁盘文件等。在视景驱动模块中,由于Vega进程和MFC主进程将运行在同一台PC上,所以主要应用于网络环境PC间的进程间通信的NetDDE、WindowsSockets、NetBIOS以及RPC都不适合,而通过磁盘文件来进行数据交换也不可行,这样就只能直接在内存中进行通信。因为在Ve


转载请注明来自:http://www.yueqikan.com/weidianziyingyonglw/990.html

上一篇:没有了

下一篇:平衡记分卡在建筑企业绩效考核中的应用