问题与此问题有些类似,但接受的答案并未真正提出解决方案或解决方法.
在我们的项目中,我们有一个dylib和主要的可执行文件.dylib使用-fno-rtti,而可执行文件使用RTTI 编译.当std::bad_alloc从dylib抛出异常(例如)并在exe中捕获时,会发生此问题.
(在你大喊"异常需要RTTI所以你必须有它!",请注意,必要的例外RTTI总是产生不管的-frtti或-fno-rtti设置.这实际上是在记录-fno-rtti标志的说明.在OS X上的问题是,它不是以相同的方式生成的)
经过一番调查,发现了以下内容:
-fno-rtti)中,有一个异常的RTTI结构的本地副本; 特别是__ZTISt9bad_alloc符号(typeinfo for std::bad_alloc).-frtti)从中导入typeinfo符号libstdc++.6.dylib,但没有本地副本由于异常处理代码依赖于比较typeinfo指针来确定异常匹配,因此匹配失败,只有catch(...)成功.
到目前为止,我看到以下选项:
1)编译所有内容,或者至少编译抛出和捕获异常的文件-frtti.这是可行的,但我不喜欢为所有东西生成RTTI的想法,即使我们不使用它; 并且使用异常的文件列表很容易变得陈旧.
2)当链接dylib时,以某种方式使链接器从目标文件中丢弃弱异常定义并使用它来自libstdc++.6.dylib.到目前为止,我没有成功.
3)???
我做了一个小测试来说明这个问题.
--- throw.cpp ---
#include <iostream>
#if defined(__GNUC__)
#define EXPORT __attribute__((visibility("default")))
#else
#define EXPORT __declspec(dllexport)
#endif
EXPORT void dothrow ()
{
std::cout << "before throw" << std::endl;
throw std::bad_alloc();
}
--- main.cpp --- …Run Code Online (Sandbox Code Playgroud) 我正在使用 AngelScript,我似乎无法理解的一件事是如何捕获从 C++ 抛出但从 AngelScript 调用的异常。这是我到目前为止所得到的:
// test.as
void main()
{
print("Calling throwSomething...");
throwSomething();
print("Call finished");
}
Run Code Online (Sandbox Code Playgroud)
void print(string)和void throwSomething()是注册到引擎的两个函数,来源如下。根据AngelScript 文档:
向脚本引擎注册的应用程序函数和类方法允许抛出 C++ 异常。虚拟机将自动捕获任何 C++ 异常、中止脚本执行并将控制权返回给应用程序。
以下是提供的用于处理异常的示例代码:
asIScriptContext *ctx = engine->CreateContext();
ctx->Prepare(engine->GetModule("test")->GetFunctionByName("func"));
int r = ctx->Execute();
if( r == asEXECUTION_EXCEPTION )
{
string err = ctx->GetExceptionString();
if( err == "Caught an exception from the application" )
{
// An application function threw an exception while being invoked from the script
...
}
}
Run Code Online (Sandbox Code Playgroud)
我几乎逐字地将这段代码复制到我的编辑器中并尝试运行它。不幸的是,即使我将调用包装Execute …