【问题标题】:c++ link stl without runtime library没有运行时库的c ++链接stl
【发布时间】:2012-09-13 19:36:28
【问题描述】:

所以我在无法链接任何运行时库或使用异常的环境中工作。但是,我们想利用 BOOST 或 STL。最初我们尝试在 boost::container::string/vector/map/... 中进行链接,但无法解决链接器错误。

所以目前我正在尝试链接 STL 的标头,为此我定义了以下预处理器指令:

#define _HAS_ITERATOR_DEBUGGING 0

#define _HAS_EXCEPTIONS 0

我能够成功地与#include 链接,并且我能够实例化一个std::vector,但是当我调用push_back(32); 时在向量上,我收到以下链接器错误:

error LNK2001: unresolved external symbol "void (__cdecl* std::_Raise_handler)(class stdext::exception const &)" (?_Raise_handler@std@@3P6AXAEBVexception@stdext@@@ZEA)
error LNK2001: unresolved external symbol _invoke_watson
error LNK2001: unresolved external symbol "void __cdecl std::_Xlength_error(char const *)" (?_Xlength_error@std@@YAXPEBD@Z)

我们使用的是 Visual Studio 2010(它是默认编译器)。我们希望在不久的将来迁移到 vs2012,如果它有助于解决这些错误,则可以加快迁移速度。

有没有办法在这些限制下链接 boost 或 STL(没有例外,没有运行时库)?

谢谢!我们真的不想因为我们的环境限制而错过 STL/boost 的好处

【问题讨论】:

  • 你到底在什么环境下!@?!?!??@!
  • 当你说运行时库是指动态/共享库还是标准库?
  • C++ 没有例外? 为什么?因为你喜欢一直检查错误代码的更慢和更大的代码?还是因为您想要更快、更小代码而忽略错误代码?没有例外也会使大多数 C++ 库对您毫无用处。 (虽然EASTL 是为无例外而设计的)
  • 可能会有所帮助:stackoverflow.com/questions/553103/…。而这个:playtechs.blogspot.com/2007/07/… 只需搜索“c++ stl without exceptions”“std::_Raise_handler”
  • @Wug 和 Mooing Duck:一种可能性是嵌入式系统。想象一下,如果一架在 30,000 英尺高空飞行的客机的飞行控制系统抛出异常会发生什么。他们是不允许的。 malloc 也不是。

标签: c++ exception stl runtime libraries


【解决方案1】:

这取决于您需要什么,但可能不需要。

C++ 标准库中的所有容器都需要内存分配,它包含在运行时库中。所以,你不能:

std::vector<>
std::set<>
std::map<>
std::list<>

你也许可以使用

std::array<>
std::tuple<>

但你也可能不会。

所有的流都需要内存分配,而且大多数流都需要文件 i/o 系统调用,所以它们也被淘汰了。

由于不能使用容器,迭代器的大部分功能不再有用。

好消息是大多数 Boost 支持仅在标头中提供,因此您无需链接 Boost 库。对于 Boost,只需尝试 #includeing 适当的标题。如果它编译和链接,你赢了。

【讨论】:

  • 但是Boost 可能也依赖异常,就像 STL 一样
  • 所以,更可能的是,“不”。
  • 当我们尝试这种方法时,我们的第一个包含引入了异常。我们包含了 boost::container::string 并实例化了一个默认字符串。我们收到有关立即使用异常的警告,在调查发现 boost::container::string 使用“throw e”后,我们将其替换为用户定义的函数 throw_exception,但由于 boost 使用 STL 时遇到了问题。由于我们使用了 STL,我们定义了 #define _HAS_EXCEPTIONS 0 来禁用 STL 异常。不幸的是,BOOST 包括 ,它的类派生自 std::exception。这对我们来说是一条死胡同。
  • 但是 OP 是否意味着在运行时加载的“共享库”。假设您需要标准运行时来运行任何 C 或 C++ 应用程序,否则将很难做任何事情。
【解决方案2】:

首先,澄清一点。您不需要 Boost 即可使用标准模板库。 STL 很久很久以前作为 C++ 标准库的一部分并入 C++。您已经将它作为 Visual Studio 2010 的一部分。

您需要澄清不能“链接任何运行时库”的意思。您甚至不允许使用标准的 C 和 C++ 运行时库吗?这意味着没有 I/O,没有数学函数,没有 new,没有 delete,什么都没有。如果允许您使用标准库,那么您已经拥有 STL。

但是,这里有一个问题。这个问题是 C++ 标准库抛出异常。异常是标准库函数报告错误的首选机制。如果这些函数无法按要求分配内存,则会抛出std::bad_alloc,当您使用检查事物是否在范围内的访问器时,它们会抛出std::out_of_range。在这些标准头文件中有很多throw 的调用。

您的“不抛出异常”仅适用于您,还是也适用于标准库?如果它适用于库以及您的程序员,您可以注销 C++ 容器、C++ I/O、C++ 字符串以及几乎所有的 Boost。

【讨论】:

  • “不抛出异常”适用于我的团队以及我们链接的库。目前我们没有链接任何运行时库,包括 C/C++ 运行时库。我们在预启动环境 (BIOS) 中运行,我们无法访问操作系统提供的任何内容(C 运行时库使用操作系统挂钩)
【解决方案3】:

为了消除标准库中的异常,您需要一个不使用异常的库构建。设置这些宏是构建和使用此类库的一部分。我不认为微软发布了他们库的无异常版本,但如果他们这样做了,你需要链接到它而不是正常的。如果没有,您需要考虑从 Dinkumware(向 Microsoft 提供该库的公司)获得该库的许可。 www.dinkumware.com。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-19
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 2011-04-09
    • 1970-01-01
    • 1970-01-01
    • 2011-01-03
    相关资源
    最近更新 更多