(这就像my other question,但这个是另一回事,即使它是相关的)
我的项目中存在一个大问题。我有一个处理XML的库,可以抛出异常。并且,使用它来创建配置文件类会显示我的第一个错误:库中根本没有处理异常,并且每个例外都没有处理异常。
在我写的图书馆中:
try {
throw std::exception();
}
catch (...)
{
printf("caught\n");
}
但是,未处理异常并立即调用std::terminate
:
terminate called after throwing an instance of 'std::exception'
what(): std::exception
编译标志是最简单的:文件库为-fPIC -std=c++11 -g -Wall
,可执行文件为-std=c++11 -g -Wall
(加上库和变体构建定义)。另外,我在Linux下使用G ++ 5.4.0(确切地说是Linux Mint)。
这是我的main
:
#include "ns/core/C_Configuration.hpp"
#include <iostream>
using namespace std;
using namespace ns;
int
main (int argc, char** argv)
{
try {
C_Configuration c ("test.xml");
c.load ("test.xml");
} catch (const std::exception& ex) {
cout << ex.what () << endl;
} catch (...) {
cout << "Caught." << endl;
}
return 0;
}
C_Configuration.hpp
:
#include <string>
#include <exception>
namespace ns
{
class C_Configuration
{
public:
C_Configuration (std::string);
bool load (std::string file);
};
} // namespace ns
而且,这是C_Configuration.cpp
:
#include "ns/core/C_Configuration.hpp"
#include <cstdio>
using namespace std;
namespace ns
{
C_Configuration::C_Configuration (string)
{ }
bool
C_Configuration::load (string file)
{
try {
throw exception();
} catch (const exception& ex) {
printf ("In C_Configuration : %s\n", ex.what ());
} catch (...) {
printf ("In C_Configuration : caught\n");
}
return true;
}
} // namespace ns
Buid命令:
g++ -m64 -g -shared -fPIC -std=c++11 -o libns_framework.so C_Configuration.cpp
g++ -m64 -g -L. -o exe main.cpp -lns_framework
注意:我举了这个例子,但它按预期工作,异常会在库中捕获,而不是像我的主项目中那样。如果您想进一步调查,可以查看我的项目代码here。
问题出在:
在任何情况下,异常都会在内部库中抛出。但是,外部抛出的异常会被可执行代码捕获:
int
main (int argc, char** argv)
{
try {
throw 1;
} catch (...) {
cout << "Caught" << endl;
}
// Useless code
return 0;
}
此代码只在输出中写入Caught
。
所以,我的问题很简单:C ++异常是否在库中处理,或者我忘记了编译标志?我需要在可执行代码中说,例外工作正常。
感谢您的帮助。
编辑:天啊,我的坏人。问题解决了。在我的构建配置的最深部分,ld
代替了g++
。现在异常工作正常。谢谢你的帮助。
答案 0 :(得分:2)
根据gcc manual:
如果库或主可执行文件应该抛出或捕获异常,则必须使用G ++或GCJ驱动程序链接它,以适合程序中使用的语言,或使用选项 -shared-libgcc < / strong>,这样它就与共享的libgcc链接。
共享库(在C ++和Java中)默认设置该标志,但不是主可执行文件。无论如何,你应该在两者上使用它。
lib.cpp :
#include "lib.hpp"
#include <string>
#include <iostream>
using namespace std;
int function_throws_int() {
try {
throw 2;
}
catch (...) {
cout << "int throws lib" << endl;
throw;
}
return -1;
}
int function_throws_string() {
try {
throw std::string("throw");
}
catch (...) {
cout << "throws string lib" << endl;
throw;
}
}
lib.hpp :
int function_throws_int();
int function_throws_string();
编译命令行:
g++ -m64 -g -shared-libgcc -shared -fPIC -std=c++11 -o libtest.so lib.cpp
的main.cpp :
#include "lib.hpp"
#include <string>
#include <iostream>
using namespace std;
int main(int argc, char ** argv) {
try {
function_throws_int();
}
catch (const string & e) {
cout << "string caught main" << endl;
}
catch (int i) {
cout << "int caught main" << endl;
}
return 0;
}
编译命令行:
g++ -m64 -g -shared-libgcc -o main -L. main.cpp -ltest
<强>执行强>:
LD_LIBRARY_PATH=. ./main
<强>输出强>:
int throws lib
int caught main
答案 1 :(得分:1)
简单。切勿在{+ 1}}中使用C ++。我将项目中的所有ld
命令更改为ld
但似乎我忘了这个库。
简而言之,我使用g++
来构建我的库,但ld
用于主可执行文件。因此,异常在可执行文件中有效但在库中没有,因为g++
不包括处理异常系统的C ++库。