错误的出现是这样的:
我在VS2008的一个工程中添加了WinDDK中头文件difxapi.h的引用,并在工程Properties->C/C++->Additional Include Directories中添加了difxapi.h所在的目录C:\WinDDK\7600.16385.1\inc\api\。
再编译时,编译器提示错误:
C:\Program Files\Microsoft Visual Studio 9.0\VC\include\new.h(60) : error C2065: '_In_opt_' : undeclared identifier
错误的原因分析:
1. 可以看出,问题出现在new.h文件,原因是_In_opt_没有被声明。那么我们来找一下是否真的如此。
在sal.h文件(VA指向了C:\Program Files\Microsoft Visual Studio 9.0\VC\include\sal.h)中,找到了_In_opt_的定义:
#define _In_opt_ _Pre_opt_valid_ _Deref_pre_readonly_
而sal.h文件在crtdefs.h文件中被include,crtdefs.h文件又被new.h文件include,这样看来,应该是正常声明过了。
2. 好吧,还有一个可能是sal.h文件不止有一个,编译器引用了错误的sal.h文件。
crtdefs.h文件引用sal.h的声明如下:
#include <sal.h>
尖括号表明了编译器将从工程文件中“/I”定义的include路径开始搜索。因为工程中添加了difxapi.h的路径,那么,自然先从C:\WinDDK\7600.16385.1\inc\api\开始找起。
果然,在该目录下,又找到了一个sal.h文件,而且,里面没有_In_opt_的定义。
错误的原因找到了,就是因为#include<sal.h>会从工程定义的include路径找起,从而引用到C:\WinDDK\7600.16385.1\inc\api\sal.h文件,而这,根本不是我们想要的。
解决方法:
解决的方法有两个:
1. 删掉C:\WinDDK\7600.16385.1\inc\api\sal.h文件,或将其换成别的名字。
这个方案可能会影响到其它驱动程序的编译,所以这里不推荐这种极端恐怖的做法。
2. 将crtdefs.h文件中引用sal.h的方式改为 #include "sal.h"
include中使用双引号时,编译器会先从调用include的文件所在目录开始找起,这样,被引用的文件将是C:\Program Files\Microsoft Visual Studio 9.0\VC\include\sal.h。
这个改动使VS2008的工程每次都引用C:\Program Files\Microsoft Visual Studio 9.0\VC\include\sal.h,但目前看来,问题不会很大。或许会对一些驱动工程造成影响,所以这样修改时还是要小心为上。