繁体   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