none
VS2008里一个有关WIA 的LNK2001: unresolved external symbol 问题 RRS feed

  • 问题

  • 我的环境: VS2008 SP1 + XP,本想写一个 XP 下 Camera 的程序,完全是从 MSDN 里 copy 的关于 WIA 的源码稍做改动,结果编译能通过,但是 LINK 的时候老是报 LNK2020/LNK2001 错,我分析了半天,实在是弄不明白怎么回事了。谁能帮我看看。
    原代码:

    // temp.cpp : Defines the entry point for the console application.
    //

    #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?
       //
       const ULONG c_nPropertyCount = sizeof(PropSpec)/sizeof(PropSpec[0]);

       //
       // Define which properties you want to read:
       // Device ID.  This is what you would use to create
       // the device.
       //
       PropSpec[0].ulKind = PRSPEC_PROPID;
       PropSpec[0].propid = WIA_DIP_DEV_ID;  //Device ID

       PropSpec[1].ulKind = PRSPEC_PROPID;
       PropSpec[1].propid = WIA_DIP_DEV_NAME;  //Device Name

       PropSpec[2].ulKind = PRSPEC_PROPID;
       PropSpec[2].propid = WIA_DIP_DEV_DESC;  //Device Description

       PropSpec[3].ulKind = PRSPEC_PROPID;
       PropSpec[3].propid = WIA_DIP_DEV_TYPE;  //Device Type

       PropSpec[4].ulKind = PRSPEC_PROPID;
       PropSpec[4].propid = WIA_DIP_BAUDRATE;  //The current baud rate setting for the device

       PropSpec[5].ulKind = PRSPEC_PROPID;
       PropSpec[5].propid = WIA_DIP_DRIVER_VERSION; //The current DLL version of the WIA minidriver

       PropSpec[6].ulKind = PRSPEC_PROPID;
       PropSpec[6].propid = WIA_DIP_HW_CONFIG;  //The type of connection that the device is using

       PropSpec[7].ulKind = PRSPEC_PROPID;
       PropSpec[7].propid = WIA_DIP_PORT_NAME;  //The installed device's port name

       PropSpec[8].ulKind = PRSPEC_PROPID;
       PropSpec[8].propid = WIA_DIP_UI_CLSID;  //The vendor-supplied class identifier (CLSID) for any user interface (UI)

       PropSpec[9].ulKind = PRSPEC_PROPID;
       PropSpec[9].propid = WIA_DIP_VEND_DESC;  //The vendor description string for the WIA minidriver

       PropSpec[10].ulKind = PRSPEC_PROPID;
       PropSpec[10].propid = WIA_DIP_WIA_VERSION; //The number (as a string) of the current WIA version that is installed on the system

       //
       // Ask for the property values
       //
       hr = pWiaPropertyStorage->ReadMultiple( c_nPropertyCount, PropSpec, PropVar );

       if (!SUCCEEDED(hr)) return 4;

       //
                // Free the returned PROPVARIANTs
                //
                FreePropVariantArray( c_nPropertyCount, PropVar );

       pWiaPropertyStorage->Release();
       pWiaPropertyStorage = NULL;
      }
     }

     return 0;
    }


    编译的时候,老是会出现 LINK 错误,我不知道是怎么回事:

    1>Linking...
    1>temp.obj : error LNK2001: unresolved external symbol _CLSID_WiaDevMgr2
    1>temp.obj : error LNK2001: unresolved external symbol _IID_IWiaDevMgr2
    1>temp.obj : error LNK2001: unresolved external symbol _CLSID_WiaDevMgr
    1>temp.obj : error LNK2001: unresolved external symbol _IID_IWiaDevMgr
    1>C:\Documents and Settings\Bryan\My Documents\Visual Studio 2008\Projects\temp\Debug\temp.exe : fatal error LNK1120: 4 unresolved externals

    可是我查了一下 wia.h 里,是有关于这4个的定义的啊。难道是VS2008 6.0A 的SDK 里 WIA 的 LIB 文件与 WIA.H 不匹配?

    2009年5月4日 7:45

答案

  • 用VC2008 Express+Windows SDK 6.1 不能重现你的问题。如果你用的是VC2008 Express附带的Windows SDK,可以升级到最新的Windows SDK看看。
    Common Language Runtime Support不会增加连接的lib。如果你仅仅增加/clr支持就可以编译通过的话,那应该是一个SDK或者C++ linker的一个BUG。

    MSMVP VC++
    2009年5月4日 21:57
    版主

全部回复

  • 有没有添加输入库: wiaguid.lib

    工程属性->配置属性->链接器->输入->附加依赖项, 加入上面的库

    相信命运
    2009年5月4日 8:40
    版主
  • 这个我有加了啦, 我在两个地方都加过,一个是你说的地方,一个是 "Project"->"Property"->"Linker"->"Input"->"Additional Dependencies", 都加了 wiaguid.lib, 而且在 LOG 里,也可以看到 WIAGUID.LIB 是包含在LINK 命令里的。

    Command Lines
       
    Creating temporary file "c:\Documents and Settings\Bryan\My Documents\Visual Studio 2008\Projects\WinTOP\Camera\Debug\RSP0000015161228.rsp" with contents
    [
    /OUT:"C:\Documents and Settings\Bryan\My Documents\Visual Studio 2008\Projects\WinTOP\Debug\Camera.exe" /INCREMENTAL /MANIFEST /MANIFESTFILE:"Debug\Camera.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /ASSEMBLYDEBUG /PDB:"C:\Documents and Settings\Bryan\My Documents\Visual Studio 2008\Projects\WinTOP\Debug\Camera.pdb" /SUBSYSTEM:WINDOWS /ENTRY:"main" /DYNAMICBASE /FIXED:No /NXCOMPAT /MACHINE:X86 wiaguid.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /ASSEMBLYRESOURCE:".\Debug\Camera.frmMain.resources"
    
    ".\Debug\AssemblyInfo.obj"
    
    ".\Debug\Camera.obj"
    
    ".\Debug\stdafx.obj"
    
    ".\Debug\app.res"
    ]
    Creating command line "link.exe @"c:\Documents and Settings\Bryan\My Documents\Visual Studio 2008\Projects\WinTOP\Camera\Debug\RSP0000015161228.rsp" /NOLOGO /ERRORREPORT:PROMPT"
    

    2009年5月4日 8:47
  • 补充一些信息: 出现LINK错误的是我用“新建向导”创建的一个叫 Camera 的 Windows forms application,编译的时候,不管加不加 wiaguid.lib,都有两个报错:
    1>Linking...
    1>Camera.obj : error LNK2020: unresolved token (0A000015) CLSID_WiaDevMgr2
    1>Camera.obj : error LNK2020: unresolved token (0A000016) IID_IWiaDevMgr2
    1>Camera.obj : error LNK2020: unresolved token (0A000017) CLSID_WiaDevMgr
    1>Camera.obj : error LNK2020: unresolved token (0A000018) IID_IWiaDevMgr
    1>Camera.obj : error LNK2001: unresolved external symbol IID_IWiaDevMgr2
    1>Camera.obj : error LNK2001: unresolved external symbol CLSID_WiaDevMgr2
    1>Camera.obj : error LNK2001: unresolved external symbol IID_IWiaDevMgr
    1>Camera.obj : error LNK2001: unresolved external symbol CLSID_WiaDevMgr

    但是我把代码复制到一个 temp 的 console application 里编译,如果不加 wiaguid.lib, 就会只有 LNK2001 报错,但是不会有 LNK2020报错,如果加了 wiaguid.lib,就可以成功编译。
    2009年5月4日 9:01
  • 我找到问题的最终答案了:

    见:http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/38de219a-a953-4dfc-aa68-5e13e7004f49
    将 "Project Properties"->"Configuration Properties"->"General"->"Common Language Runtime support" 设置为"Common Language Runtime Support /clr"解决,默认的这里是“No Common Language Runtime Support".
    2009年5月4日 15:37
  • 用VC2008 Express+Windows SDK 6.1 不能重现你的问题。如果你用的是VC2008 Express附带的Windows SDK,可以升级到最新的Windows SDK看看。
    Common Language Runtime Support不会增加连接的lib。如果你仅仅增加/clr支持就可以编译通过的话,那应该是一个SDK或者C++ linker的一个BUG。

    MSMVP VC++
    2009年5月4日 21:57
    版主
  • 用VC2008 Express+Windows SDK 6.1 不能重现你的问题。如果你用的是VC2008 Express附带的Windows SDK,可以升级到最新的Windows SDK看看。
    Common Language Runtime Support不会增加连接的lib。如果你仅仅增加/clr支持就可以编译通过的话,那应该是一个SDK或者C++ linker的一个BUG。

    MSMVP VC++

    正解。昨晚下了最新的 v7.0 SDK(7000.0.4011),  然后改回 "No Common Language Runtime Support", 也能编译通过了,看来真是 v6.0A SDK 的一个 BUG.
    2009年5月5日 2:02