【问题标题】:Unresolved external 'std::char_traits<char>::assign(char *, unsigned int, char)'未解析的外部 'std::char_traits<char>::assign(char *, unsigned int, char)'
【发布时间】:2015-06-30 21:03:54
【问题描述】:

我正在努力将一些旧代码引入 C++Builder XE7 环境。当我使用低级 i/o 库编译一个小型独立工具时,我收到此错误:

[ilink32 Error] Error: Unresolved external 'std::char_traits<char>::assign(char *, unsigned int, char)' referenced from <library>|mydate

mydate 类并不复杂,只有一个函数真正使用了 STL 类,即字符串(惊喜!)。如果我注释掉一个函数的内容,错误就会消失。该代码粘贴在下面,但在查看之前,需要注意一些事项:

  1. 这段代码是很久以前写的。我在 C++ Builder 6 开发环境中继承了它。几年前,我把它带到了 C++ Builder 2010,在那里它似乎工作得很好。

  2. 它这样做的部分原因是该代码也是为非 VCL 环境编译的。一切都在 char * 上标准化,因为它是可移植的。

  3. 我的第一个猜测是这是一个宽/窄字符串问题。我认为它应该都是窄字符串,但我无法以编译器喜欢的方式明确地缩小所有内容。

  4. 1234563作者正在使用其他 STL 类(地图等),或者他正在使用它来托管一个字符数组,他正在使用指针漫游(通常与下面的示例类似地进行手动标记)。
  5. 我没有能力让所有这些代码都达到 21 世纪的 C++ 标准。我确信有更好的方法来做这些事情,但是我没有足够的时间来重写/更新这个产品套件中的数百万行代码。我的目标是了解为什么这段代码现在会导致问题,以及如何通过尽可能少的更改来修复它。

  6. 据我所知,该方法甚至没有被应用程序调用。

  7. 类名已更改以保护有罪者。

所以,就是这样。您能告诉我为什么会导致上述链接错误吗?

非常感谢!

-凯伦

string myDate::Format(const char* format) const
{
    string output;

    if (julian == 0)
        return output;

    while (format[0] != '\0')
    {
        if (format[0] == 'm')
        {
            if (format[1] == 'm')
            {
                if (format[2] == 'm')
                {
                    if (format[3] == 'm')
                    {
                        // mmmm Full name of month.
                        output += CMonthName();
                        format += 4;
                    }
                    else
                    {
                        // mmm Three letter abbreviation of month.
                        output += CMonthAbbr();
                        format += 3;
                    }
                }
                else
                {
                    // mm Two digit month (zero fill).
                    const char* ptr = CMonth();
                    if (ptr[1] == '\0')
                        output += '0';
                    output += ptr;
                    format += 2;
                }
            }
            else
            {
                // m One or two digit month (blank fill). 
                const char* ptr = CMonth();
                if (ptr[1] == '\0')
                    output += '0';
                output += ptr;
                format += 1;
            }
        }
        else if (format[0] == 'd')
        {
            if (format[1] == 'd')
            {
                if (format[2] == 'd')
                {
                    if (format[3] == 'd')
                    {
                        // dddd Full name of day of week. 
                        output += CDayName();
                        format += 4;
                    }
                    else
                    {
                        // ddd Three letter abbreviation of day of week.
                        output += CDayAbbr();
                        format += 3;
                    }
                }
                else
                {
                    // dd Two digit day of month (zero fill). 
                    const char *ptr = CDay();
                    if (ptr[1] == '\0')
                        output += '0';
                    output += ptr;
                    format += 2;
                }
            }
            else
            {
                // d One or two digit day of month (blank fill). 
                const char *ptr = CDay();
                if (ptr[1] == '\0')
                    output += ' ';
                output += ptr;
                format += 1;
            }
        }
        else if (format[0] == 'y')
        {
            if (format[1] == 'y')
            {
                if (format[2] == 'y')
                {
                    if (format[3] == 'y')
                    {
                        // yyyy Four digit year. 
                        output += CYear();
                        format += 4;
                    }
                    else
                    {
                        // yyy Not valid (use \y\y\y for yyy) 
                        return string();
                    }
                }
                else
                {
                    // yy Two digit year (zero fill). 
                    const char *ptr = CYearAbbr();
                    if (ptr[1] == '\0')
                        output += '0';
                    output += ptr;
                    format += 2;
                }
            }
            else
            {
                // y Not valid (use \y or y) 
                return string();
            }
        }
        else if (format[0] == '\\')
        {
            if (format[1] != '\0')
            {
                output += format[1];
                format += 2;
            }
        }
        else if (format[0] == ';')
        {
            // ignore rest of format text
            break;
        }
        else
        {
            output += format[0];
            format += 1;
        }
    }

    return output;
}

【问题讨论】:

  • 正如您所提到的,这可能是 charwchar_t 的问题。但这会在项目选项中进行配置,因此您可能应该检查并在此处发布您有哪些选项。您可以检查C++ (Shared Options) 部分并查看_TCHAR 映射到什么。也许你只需要指定 char 而不是 wchar_t 这是新项目的默认值,IIRC。
  • 它设置为wchar_t,这是我们需要与我们在UI中使用的VCL控件交互的东西。据我了解,这应该只影响System::String,而不是string(来自Dinkumware stl)。至少在 CBB2010 中似乎是这样。如果我错了,我将经历巨大的痛苦。
  • 您可以尝试将其更改为 char 看看会发生什么。但是,如果您使用 String 类型(仅是别名)并使用 .c_str() 访问其字节并假设它是 char * 那么是的,移动所有内容可能会有些困难。一种可能的选择是不使用System::String,而是使用AnsiString。这样,当通过.c_str() 访问时,您将获得一个char * 缓冲区,如果您从 UI 分配,则转换会在 UnicodeString 和 AnsiString 之间自动发生。
  • 感谢您的建议,罗德里戈,这就是我试图做的,但没有成功。我希望有人可能对为什么这不再起作用提出建议,所以我不会盲目地重写它。感谢您的帮助!

标签: string stl linker c++builder


【解决方案1】:

在 E:\Embarcadero\RAD Studio\8.0\include\boost_1_39\boost\test\utils\basic_cstring\basic_cstring.hpp 中,在部分赋值运算符中,添加以下行:

basic_cstring& assign( basic_cstring const& s ) { *this = basic_cstring( s.begin(), s.end() );返回*这个; }

这对我有用!

【讨论】:

    【解决方案2】:

    我只是遇到了与此非常相似的问题,并想我会分享我的解决方案

    在 Projection Options > C++ Linker 我启用了带动态 RTL 的链接,它开始为我愉快地链接

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-19
      • 1970-01-01
      • 2012-03-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多