DirectX 9.0c已经不包含DirectShow了,相应的在windows SDK中加入了DirectShow。为了方便开发,我下载了DirectX 9.0b的版本,安装到PC中。安装完后就是配置EVC的开发环境和Visual Stidio2008的开发环境。我发现我似乎已经抛弃了VC6,然而做起Wince的开发,还是习惯VC6风格的EVC,尽管2008也能够做这些事情。
一、首先配置EVC的开发环境(在VS2008下的设置方法类似)。
1、随便建立一个EVC的工程,比如MFC application。在一个源文件中包含DS的头文件
#include <streams.h>
2、配置链接库文件。
菜单中选择Project|Settings|Link,在弹出的对话框中的Category中选择General,然后在Object/library modules中输入
DEBUG版本下输入 strmbasd.lib, msvcrtd.lib, winmm.lib
Release版本 strmbase.lib, msvcrt.lib, winmm.lib
并且选中Ignore all default libraries
DirectShow SDK建议,DirectShow应用程序应该至少连接库文件strmiids.lib和quartz.lib。前者定义了DirectShow标准的CLSID和IID,后者定义了导出函数AMGetErrorText(如果应用程序中没有使用到这个函数,也可以不连接这个库)。如果程序里包含了头文件streams.h,则一般库文件还要连接strmbasd.lib、uuid.lib、winmm.lib。
3、将DirectShow的目录加入到编译环境中。选择Tools|Options|Directories,在弹出的对话框中的Show directories for中选择Include files,配置如下:
C:/DXSDK/Include
C:/DXSDK/SAMPLES/C++/DIRECTSHOW/BASECLASSES
C:/DXSDK/SAMPLES/C++/COMMON/INCLUDE
C:/Program Files/Windows CE Tools/wce500/mini2440/Include/ARMV4I
C:/Program Files/Windows CE Tools/wce500/mini2440/mfc/include
C:/Program Files/Windows CE Tools/wce500/mini2440/atl/include
再在Show directories for中选择Library files,配置如下:
C:/DXSDK/Lib
C:/DXSDK/SAMPLES/C++/DIRECTSHOW/BASECLASSES/RELEASE
C:/DXSDK/SAMPLES/C++/DIRECTSHOW/BASECLASSES/RELEASE
C:/Program Files/Windows CE Tools/wce500/mini2440/lib/ARMV4I
C:/Program Files/Windows CE Tools/wce500/mini2440/mfc/lib/ARMV4I
C:/Program Files/Windows CE Tools/wce500/mini2440/atl/lib/ARMV4I
上面的两个配置中,前面几项都是安装DirectX的路径,后面是安装BSP开发包时默认的路径,这里要注意一定要把DirectShow的路径放在前面,这样才能让程序在编译时先查找DS的路径,因为有些文件中的定义在DS和EVC中会有重复。DIRECTSHOW/BASECLASSES/DEBUG和DIRECTSHOW/BASECLASSES/RELEASE两个目录是没有的,这里也依然先加上他,后面再编译baseclasses.dsw生成这两个目录。
4、上述工作完成后,编译,出现一个错误:
c:/dxsdk/include/strmif.h(6167) : error C2011: '_RGNDATAHEADER' : 'struct' type redefinition
c:/dxsdk/include/strmif.h(6176) : error C2011: '_RGNDATA' : 'struct' type redefinition
这个文件是DS的一个头文件,而定义的这两个模块在一个系统文件中也存在定义,wingdi.h,所以会有重复定义。分析strmif.h中的该模块定义处,发现前面有一个#ifndef _WINGDI_语句,因此在这句之前加上一句
#define _WINGDI_
就解决了问题。但是两个文件中模块定义都不能删掉,可能是在别的地方还有调用吧。
这时再编译,会出现cannot open input file 'strmbasd.lib'的错误。下面编译baseclasses.dsw工程。
二、VS2008编译baseclasses.dsw。用VS2008打开工程文件,默认转换后,编译。
出现一堆的错误,其根源是这个错误
错误1:
C:/Program Files/Microsoft SDKs/Windows/v6.0A/include/winnt.h(236) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
定位到那一行,
typedef void *PVOID;
typedef void * POINTER_64 PVOID64;
在它之前加下:
#define POINTER_64 __ptr64
这样就可以解决了。
错误2:
>c:/DXSDK/Samples/C++/DirectShow/BaseClasses/ctlutil.h(280) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
定位到那一行,将 COARefTime(LONG); operator=(LONG);
改变成 COARefTime & operator=(LONG);
错误3:
missing type specifier - int assumed. Note: C++ does not support default-int
编译时会出现很多这样的错误,这是因为VC2008相比VC6,对C++标准有了更严格的支持。出现这样的问题,只需在定义前面加上int显示定义就可以了。
参考文章:http://www.cppblog.com/sandy/archive/2006/03/13/4081.aspx
警告1:
warning C4996: '_vswprintf': This function or variable may be unsafe
后面的解释说了用_vswprintf'_s函数代替_vswprintf',先不管为什么,照着做。
警告2:
warning C4603: '_WINDLL' : macro is not defined or definition is different after precompiled header use
后面也有解释,把这个定义添加到预编译头文件中。于是在streams.h中添加#define _WINDLL,同时把原来的定义注释掉
错误4:
./winutil.cpp(2104) : error C2065: 'Count' : undeclared identifier
在文件中查找Count的定义,发现是在一个for循环中,这种定义是VC6.0的习惯,VC2008严格支持C++标准,所以Count只能在for内使用。把其放到for外面就可以了。
再编译还有一个iDone未定义的错误,原因与上面一样的。
再编译就没有错误了,成功生成./DEBUG/strmbasd.lib,激活release,再编译生成了./RELEASE/strmbase.lib