簡體   English   中英

錯誤 LNK2001:Visual Studio 2019 中未解析的外部符號 CWbemProviderGlue::FrameworkLogoffDLL(wchar_t const *)"

[英]error LNK2001: unresolved external symbol CWbemProviderGlue::FrameworkLogoffDLL(wchar_t const *)" in Visual Studio 2019

有一些最初為 Windows 2000 和 WMI SDK 設計的代碼。 我正在嘗試解決 linker 錯誤。 在嘗試了什么是未定義的引用/未解決的外部符號錯誤中引用的選項后,我該如何解決? 無法找到解決方案。

未解決的符號錯誤:

1>WmiProvider.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __thiscall Provider::Provider(wchar_t const *,wchar_t const *)" (__imp_??0Provider@@QAE@PB_W0@Z)
1>WmiProvider.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: bool __thiscall CInstance::SetCHString(wchar_t const *,char const *)" (__imp_?SetCHString@CInstance@@QAE_NPB_WPBD@Z)
1>dllmain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: static int __stdcall CWbemProviderGlue::FrameworkLogoffDLL(wchar_t const *)" (__imp_?FrameworkLogoffDLL@CWbemProviderGlue@@SGHPB_W@Z)
1>dllmain.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: static int __stdcall CWbemProviderGlue::FrameworkLoginDLL(wchar_t const *)" (__imp_?FrameworkLoginDLL@CWbemProviderGlue@@SGHPB_W@Z)

我試過添加代碼:

#pragma comment(lib,"Framedyn.lib")

並嘗試將 lib 添加到framedyn.lib linker 選項,但仍然出現相同的錯誤。

該項目定義了以下內容以允許在 Windows XP 上運行:

#define _WIN32_WINNT 0x0501

項目設置包括:

  • 目標平台版本 7.0
  • 平台工具集 Visual Studio 2017 - Windows XP (v141_xp)
  • C++ 語言標准默認值(ISO C++14 標准7)
  • 語言 - 一致性模式 - 否
  • 目標 X86

示例用法:

case DLL_PROCESS_ATTACH:
    ghModule = hInstDLL;
    bRet = CWbemProviderGlue::FrameworkLoginDLL(L"WmiProvider");
    break;

CL.exe 和 MSBUILD.exe 從以下位置加載WbemGlue.h

C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Include\WbemGlue.h

link.exe 從以下位置加載FrameDyn.lib

C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Lib\FrameDyn.Lib

dumpbin /exports "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Lib\FrameDyn.Lib" 將 FrameworkLoginDLL 的條目顯示為:

?FrameworkLoginDLL@CWbemProviderGlue@@SGHPBG@Z (public: static int __stdcall CWbemProviderGlue::FrameworkLoginDLL(unsigned short const *))
?FrameworkLoginDLL@CWbemProviderGlue@@SGHPBGPAJ@Z (public: static int __stdcall CWbemProviderGlue::FrameworkLoginDLL(unsigned short const *,long *))

查看符號差異是當我編譯 Visual Studio 時正在尋找FrameworkLoginDLL@CWbemProviderGlue@@SGHPB_W@Z而 lib 文件末尾有一個 G 並且沒有W ie **FrameworkLoginDLL@CWbemProviderGlue@@SGHPBG @Z**

舊的 MSDN 文檔(從 2001 年 8 月開始)指定了這種用途:

當將 DLL_PROCESS_ATTACH 值發送到 DllMain 以確定是否可以加載提供程序服務器時調用 FrameworkLoginDLL 方法。

static BOOL WINAPI CWbemProviderGlue::FrameworkLoginDLL(
  LPCWSTR name
);

要求:

  • Windows NT/2000/XP:包含在 Windows NT 4.0 SP4 及更高版本中。
  • Windows 95/98/Me:包含在 Windows 95 及更高版本中。
  • Header:在 WbemGlue.h 中聲明; 包括 FwCommon.h。
  • 庫:使用 Framedyn.lib。

此處的當前文檔指定使用:

BOOL FrameworkLoginDLL(
  LPCWSTR name
);

有以下要求:

  • 支持的最低客戶端 Windows Vista
  • 最低支持服務器 Windows 服務器 2008
  • 目標平台 Windows Header wbemglue.h(包括 FwCommon.h)
  • 庫 FrameDyn.lib
  • DLL FrameDynOS.dll; FrameDyn.dll

使用桌面 C++ 向導創建新的 Visual Studio 2019 項目,選擇 DLL 和所有其他默認值,使用此代碼重現相同的問題:

#include "framework.h"
#include <FwCommon.h>
#pragma comment(lib,"FrameDyn.lib")
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    BOOL bRet = TRUE;

    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        bRet = CWbemProviderGlue::FrameworkLoginDLL(L"WmiProvider");

    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return bRet;
}

拆解符號 linker 正在嘗試使用獲取以下內容:

__imp_public: static int __stdcall CWbemProviderGlue::FrameworkLoginDLL(wchar_t const *)

對實際.lib 文件中的符號進行拆解:

public: static int __stdcall CWbemProviderGlue::FrameworkLoginDLL(unsigned short const *)

WbemGlue.h 中的定義

static BOOL WINAPI FrameworkLoginDLL(LPCWSTR name);

出現此問題是因為 MSVC 正在尋找符號FrameworkLoginDLL@CWbemProviderGlue@@SGHPB_W@Z但 lib 文件具有定義FrameworkLoginDLL@CWbemProviderGlue@@SGHPBG@Z

使用https://demangler.com/對名稱進行拆解顯示 MSVC 使用的符號是:

__imp_public: static int __stdcall CWbemProviderGlue::FrameworkLoginDLL(wchar_t const *)

lib文件在哪里:

public: static int __stdcall CWbemProviderGlue::FrameworkLoginDLL(unsigned short const *)

通過將C/C++ - Language - Treat WChart As Built in Type下的 Project Properties 設置為No (/Zc:wchar_t-)解決了這個問題

在此處輸入圖像描述

Microsoft 在此處建議有關此設置的以下內容:

如果 /Zc:wchar_t 打開,wchar_t 是編譯為 C++ 的代碼中內置整數類型的關鍵字。 如果指定了 /Zc:wchar_t-(帶減號),或者在編譯為 C 的代碼中,wchar_t 不是內置類型。 相反,wchar_t 在規范 header stddef.h 中被定義為 unsigned short 的 typedef。 (Microsoft 實現在 stddef.h 和其他標准頭文件中包含的另一個 header 中對其進行了定義。)

我們不推薦 /Zc:wchar_t- 因為 C++ 標准要求 wchar_t 是內置類型。 使用 typedef 版本可能會導致可移植性問題。 如果您從早期版本的 Visual Studio 升級並遇到編譯器錯誤 C2664,因為代碼試圖將 wchar_t 隱式轉換為 unsigned short,我們建議您更改代碼以修復錯誤,而不是設置 /Zc:wchar_t-。

/Zc:wchar_t 選項在 C++ 編譯中默認打開,在 C 編譯中被忽略。 /permissive- 選項不影響 /Zc:wchar_t。

Microsoft 將 wchar_t 實現為兩字節無符號值。 它映射到 Microsoft 特定的本機類型 __wchar_t。 有關 wchar_t 的更多信息,請參閱數據類型范圍和基本類型。

如果您編寫的新代碼必須與仍然使用 wchar_t 的 typedef 版本的舊代碼互操作,您可以為 wchar_t 的 unsigned short 和 __wchar_t 變體提供重載,以便您的代碼可以與使用 /Zc 編譯的代碼鏈接: wchar_t 或沒有它編譯的代碼。 否則,您將必須提供兩種不同的庫版本,一種啟用/Zc:wchar_t 啟用,另一種未啟用/Zc:wchar_t。 即使在這種情況下,我們也建議您使用用於編譯新代碼的相同編譯器來構建舊代碼。 切勿混合使用不同編譯器編譯的二進制文件。

當指定 /Zc:wchar_t 時,定義了 _WCHAR_T_DEFINED 和 _NATIVE_WCHAR_T_DEFINED 符號。 有關詳細信息,請參閱預定義宏。

如果您的代碼使用編譯器 COM 全局函數,因為 /Zc:wchar_t 現在默認打開,我們建議您將對 comsupp.lib 的顯式引用(從注釋編譯指示或命令行上)更改為 comsuppw.lib 或comsuppwd.lib。 (如果必須使用 /Zc:wchar_t- 進行編譯,請使用 comsupp.lib。)如果包含 comdef.h header 文件,則會為您指定正確的庫。 有關編譯器 COM 支持的信息,請參閱編譯器 COM 支持。

編譯 C 代碼時不支持 wchar_t 內置類型。 有關 Visual C++ 的一致性問題的更多信息,請參閱非標准行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM