我的环境是 VS2008 SP1 + XP SP3, 本来打算写一个基于WIA的摄像头程序,所以这两天就把MSDN里的"Win32 and COM"->"Graphics and Multimedia"->"Windows Image Acquisition"->"WIA" 完完全全的看了一遍。然后试着按它里面的 "WIA Tutorial"把样本代码直接复制出来,想罗列一下当前系统里的 WIA Device, 结果发现编译能通过,但是老是报 error LNK2001: unresolved external symbol _CLSID_WiaDevMgr2,分析了半天,"WIA.H" 也是指向的正确的 VS2008 6.0A 的SDK,没有问题,我的源码里也已经加了 "windows.h","wia.h", 但 unresolved external symbol 错误就是要出来,难道是 6.0A SDK 里的 wia.h 和 lib 文件不匹配?还是 WIA.H 有问题?
6.0A的SDK已经支持 Vista, 所以我看 wia.h 里根据 _WIN32_WINNT 来包含 wia_lh.h 或 wia_xp.h
#if (_WIN32_WINNT >= 0x0600) // Longhorn
#include <wia_lh.h>
#elif (_WIN32_WINNT >= 0x0501) // Windows XP
#include <wia_xp.h>
#endif
从windows.h 反向追踪到 sdkddkver.h, 里面定义的是 #define _WIN32_WINNT 0x0600, 所以可以确认是引用的 wia_lh.h, 在 wia_lh.h 里,我是可以看到
EXTERN_C const CLSID CLSID_WiaDevMgr2;
#ifdef __cplusplus
class DECLSPEC_UUID("B6C292BC-7C88-41ee-8B54-8EC92617E599")
WiaDevMgr2;
#endif
这种定义的, 所以就不知道为啥为有LINK ERROR.
源代码很短,基本上就是从 MSDN 里 copy 出来的, 用的是 console 程序, 哪位如果有跟我相同的编译环境,可以帮我试试,看是不是一样的报错,能帮我解决问题就最好了。
#include "stdafx.h"
#include <windows.h>
#include <wia.h>
#include <stdio.h>
int _tmain(int argc, _TCHAR* argv[])
{
OSVERSIONINFOEX osvi;
BOOL bOsVersionInfoEx;
BOOL bOsVistaOrLater;
IWiaDevMgr **ppWiaDevMgr;
IWiaDevMgr2 **ppWiaDevMgr2;
HRESULT hr;
ppWiaDevMgr = NULL;
ppWiaDevMgr2 = NULL;
//Identify the OS version, XP or earlier use WIA interface, Vista or later will use WIA2 interface
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
return 1;
if ( osvi.dwMajorVersion >= 6 && osvi.dwMinorVersion > 0 )
bOsVistaOrLater = true; //Vista later
else if ( osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0 )
{
if( osvi.wProductType == VER_NT_WORKSTATION )
bOsVistaOrLater = true; //Vista
else bOsVistaOrLater = false; //Windows Server 2008
}
else if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 )
bOsVistaOrLater = false; //Windows 2000
else if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 )
bOsVistaOrLater = false; //Windows XP
else if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 )
bOsVistaOrLater = false; //Windows Server 2003
else
bOsVistaOrLater = false; //Windows 98/Me/NT, etc...
//Create WIA Device Manager Object
*ppWiaDevMgr = NULL;
*ppWiaDevMgr2 = NULL;
if ( bOsVistaOrLater = false )
hr = CoCreateInstance( CLSID_WiaDevMgr, NULL, CLSCTX_LOCAL_SERVER, IID_IWiaDevMgr, (void**)ppWiaDevMgr );
else
hr = CoCreateInstance( CLSID_WiaDevMgr2, NULL, CLSCTX_LOCAL_SERVER, IID_IWiaDevMgr2, (void**)ppWiaDevMgr2 );
if (!SUCCEEDED(hr)) return 2;
IEnumWIA_DEV_INFO *pWiaEnumDevInfo = NULL;
if (bOsVistaOrLater = false)
hr = (*ppWiaDevMgr)->EnumDeviceInfo( WIA_DEVINFO_ENUM_LOCAL, &pWiaEnumDevInfo );
else
hr = (*ppWiaDevMgr2)->EnumDeviceInfo( WIA_DEVINFO_ENUM_LOCAL, &pWiaEnumDevInfo );
if (!SUCCEEDED(hr)) return 3;
while (S_OK == hr)
{
IWiaPropertyStorage *pWiaPropertyStorage = NULL;
hr = pWiaEnumDevInfo->Next( 1, &pWiaPropertyStorage, NULL );
if (hr == S_OK)
{
//
// Declare PROPSPECs and PROPVARIANTs, and initialize them to zero.
//
PROPSPEC PropSpec[11] = {0};
PROPVARIANT PropVar[11] = {0};
//
// How many properties are you querying for?