错误 LNK2001:未解析的外部符号“受保护:从 VS 2010 升级到 VS 2017 时的静态枚举正则表达式

error LNK2001: unresolved external symbol "protected: static enum regex when upgrading from VS 2010 to VS 2017

我接到了将 VC++ 6.0 解决方案升级到 VS C++ 2017 的任务。根据本网站上的各种文章,我得到了使用 VS C++ 2010 正确构建的解决方案. 但是现在,当我尝试将解决方案从 VS 2010 升级到 VS 2017 时,我遇到了一个我似乎无法弄清楚的 link 错误。该解决方案使用旧的 MS regexpr2 class。我曾考虑过删除 regexpr2 class 并加入一些新的东西,但我想我会尝试看看我是否可以先构建一些东西,以免摇摇欲坠。

我得到的 linking 错误是这样的:

1>regexpr2.obj:错误 LNK2001:未解析的外部符号“受保护:静态枚举 regex::TOKEN const * const regex::perl_syntax_base::s_rgreg” (?s_rgreg@perl_syntax_base@regex@@1QBW4TOKEN@2@B) 1>regexpr2.obj : error LNK2001: 未解析的外部符号“protected: static enum regex::TOKEN const * const regex::perl_syntax_base::s_rgescape” (?s_rgescape@perl_syntax_base@regex@@ 1QBW4令牌@2@B)

如果我查看 VS 2010 成功构建的 .map 文件,我可以看到:

0002:00050550 ?s_rgreg@perl_syntax_base@regex@@1QBW4TOKEN@2@B 00000001801ce550 syntax2.obj 0002:00050a20 ?s_rgescape@perl_syntax_base@regex@@1QBW4TOKEN@2@B 00000001801cea20 syntax2.obj

在 Syntax.h 文件中我看到了这个:

class perl_syntax_base
{
protected:
    perl_syntax_base()
    {
    }

    static TOKEN const s_rgreg[ UCHAR_MAX + 1 ];
    static TOKEN const s_rgescape[UCHAR_MAX + 1];

还有像这样的各种用法:

 TOKEN tok = look_up( *icur, s_rgreg );

在 Syntax.cpp 文件中我看到了这个:

namespace regex
{

REGEX_SELECTANY TOKEN const perl_syntax_base::s_rgreg[ UCHAR_MAX + 1 ] =
{
/*  0*/    NO_TOKEN,  NO_TOKEN, NO_TOKEN,      NO_TOKEN,    NO_TOKEN,  NO_TOKEN,   NO_TOKEN, NO_TOKEN,
...}

同样来自 Syntax2.h 和 Syntax.cpp 文件的是:

Syntax2.h

extern posix_charset_type const g_rgposix_charsets[];

Syntax2.cpp

namespace detail
{

REGEX_SELECTANY extern posix_charset_type const g_rgposix_charsets[] =
{
    { "[:alnum:]",    9 },
    { "[:^alnum:]",  10 },
...}

g_rgposix_charsets变量没有link错误,从VS2010的.map文件我可以在syntax2.obj文件

中看到这个

似乎这个解决方案是

error LNK2001: unresolved external symbol "private: static class

VS 2012 error LNK2001: unresolved external symbol

但据我所知,我已经在适当地进行初始化了。

知道为什么 VS 2017 抱怨这个但 VS 2010 成功构建了吗?

提前致谢

问题 1

Subtracter.obj : error LNK2019: unresolved external symbol "protected: bool __thiscall regex::detail::basic_rpattern_base_impl<class std::_String_const_iterator

此错误的原因是,DEFAULT_BLOCK_SIZE()、_ok_to_recurse() 和其他函数的定义在 regexpr2.cpp 中可用,因此您有两种选择,要么编译整个 Greta 库填充到单独的项目中,并将结果 .lib 的引用提供给该项目。 regexpr2.cppsyntax2.cpp 包含到 .vcxproj 的 'Source Files' 文件夹中,结果将生成这两个文件的 .obj 文件并且 link 成功。

问题 2 问题1解决后,主要问题依然存在

regexpr2.obj : error LNK2001: unresolved external symbol "protected: static enum regex::TOKEN const * const regex::perl_syntax_base::s_rgreg" (?s_rgreg@perl_syntax_base@regex@@1QBW4TOKEN@2@B) 1>regexpr2.obj : error LNK2001: unresolved external symbol "protected: static enum regex::TOKEN const * const regex::perl_syntax_base::s_rgescape" (?s_rgescape@perl_syntax_base@regex@@1QBW4TOKEN@2@B)

这个问题是因为REGEX_SELECTANY

# define REGEX_SELECTANY        __declspec(selectany)

我不确定如何修改此代码,因为 Greta 库理解起来非常耗时,而且它是来自 Microsoft.there 的非常旧的代码,根据最新的 visual studio 进行了许多语法和其他更改VC++ 发生了变化,所以在解决这个问题后,您的代码可能会编译并 link 成功,但执行时会出现问题,但无论如何让我们转向解决方案,

如果我们从“syntax2.cpp”

中的下面的行中删除 REGEX_SELECTANY,这个 link 错误就会解决
REGEX_SELECTANY TOKEN const perl_syntax_base::s_rgescape[ UCHAR_MAX + 1 ] =
REGEX_SELECTANY TOKEN const perl_syntax_base::s_rgreg[UCHAR_MAX + 1] =

如果您想了解有关 __declspec(selectany) 的更多信息,请参阅此内容。

经过一番苦思冥想,我想出了如何解决 link 过程中缺少符号的问题

在syntax.h文件中有两个定义:

static TOKEN const s_rgreg[ UCHAR_MAX + 1 ];
static TOKEN const s_rgescape[UCHAR_MAX + 1];

这些文件的原始声明在 syntax.cpp 文件中:

REGEX_SELECTANY TOKEN const perl_syntax_base::s_rgreg[UCHAR_MAX + 1] =
{...}

REGEX_SELECTANY TOKEN const perl_syntax_base::s_rgescape[UCHAR_MAX + 1] =
{..}

我将它们注释掉并将这些声明移至 regexpr2.cpp 文件。

进行此更改后,我能够在没有 link 错误的情况下进行完整构建,并确认一切正常。

感谢酒窝的帮助。