星期四, 十月 05, 2006

WINX支持DirectX,OpenCV吗?

偶尔也会听到这样的一些疑问:WINX支持DirectX,OpenCV吗?也会听到SmartWin支持OpenCV这样的说法。下面我们分析一下这个问题。

我们知道,库之间共存的障碍,主要有以下几点:

其一:编译期的符号(指类名、函数名、宏名等)冲突。主要表形在:

  • 宏名冲突(由于没有命名空间的保护)。
  • 基本类型的typedef。有不少库喜欢自己typedef一下所有的基本类型。如uint32, int32等。由于这些类型非常常见,并且typedef发生在全局命名空间,冲突的概率就很大。

其二:链接期的符号冲突。根据我的经验,这主要表现在:

  • 库之间的符号冲突,即两个库同时提供了某个函数。最为典型的是全局new/delete算符的重载C++允许重载全局new/delete算符,这真的是一场灾难。在两个库同时重载了new/delete时,就出现了符号冲突(可能也会在编译期体现,但常见的情况在链接期才表现出来)。
  • 使用了不同模式的C库。如果两个静态库(Static Library)使用了不同模式的C库,那么他们将出现大量的符号冲突。而我们知道,Visual C++提供了6种模式的C库:
      Single-Threaded
      Debug Single-Threaded
      Multithreaded
      Debug Multithreaded
      Multithreaded DLL
      Debug Multithreaded DLL
  • 不同编译器编译的静态库(Static Library)不能共存。原因主要亦在于使用了不同的C库。

其三:框架的假设。一些库是以框架方式提供的,要求用户按照其预定的方式进行调用。如果两个库均提供了框架,那么他们互不知晓的情况下,通常很难在一起工作。

其四:调用的假设。在你调用一个库的代码时,你需要模拟出它需要的环境。可分为两种情形:

  • 显式的依赖。例如,你要调用QT的函数,很多时候,你需要in/out一个QString参数。当然,既然你用了QT,生成一个QString还是很容易。但是如果某个函数要求传入QWidget*指针呢?除非你的窗体(Widget)本来就是QT实现的,不然这个QWidget*的生成还是颇费脑筋。
  • 隐式的依赖。例如,你要调用MFC的一段代码,而该代码使用了AfxGetApp或者其他。那么显然你的程序需要有AfxGetApp。你的本意可能只是需要一个MFC组件,最后你却发现,最终你不得不依赖一个MFC框架(Framework)。又如ATL/WTL的_Module,ATL/WTL本身架构精巧,但是_Module很要命。个人认为它破坏了ATL/WTL本身的纯洁。因为它其实与AfxGetApp并无二致,最终导致了强耦合的结构。

WINX如何解决这些问题?

其一:编译期的符号冲突。WINX使用namepsace尽量减少对全局命名空间的污染。对宏名亦采用类namespace的解决方案,多数WINX的宏名均以“WINX_”开头。

其二:链接期的符号冲突。和STL一样,WINX的代码尽量以纯头文件的方式提供。

其三:框架的假设。WINX不是框架,以便有更好的适应性。

其四:调用的假设。WINX的函数规格尽量减少采用WINX特有的数据结构。另外,类似MFC的AfxGetApp(),WTL的_Module的全局性数据,这在WINX中是明令禁止的(只是由于WINX使用部分WTL的代码,一些时候,_Module的使用不能避免)。

所有这一切,均是为了让WINX在最大程度上和更多的库可以协作。而我们在前面也已经提到了,WINX尽量采用了更为开放的结构。相比之下,它更懂得与其他库一起协作的道理。

没有评论: