【发布时间】:2012-02-21 16:15:45
【问题描述】:
我需要使用 .lib 文件 (MSVC) 编写 C++ API,它由几个从 Dll 公开的导出 C++ 类组成。根据我对另一个问题的回答,我理解,如果 C++ API 是在一个 VC++ 版本(比如说 2010 年)中构建的,并且客户端代码是用另一个 VC++ 版本编写的,那么导出的类方法不能使用异常。由于异常不能成为公共 API 接口的一部分,因此我正在寻找另一种错误处理策略。我的限制:我不想使用 COM,丰富的错误代码系统(如 HRESULT)对我来说还不够。我想要一个类异常类,其中包含错误代码、错误消息和我需要的任何其他信息。另外,我不想为每个 VC++ 版本单独构建。
我目前的方法如下。每个公共类方法都返回枚举值(如 ErrorCode)。在方法失败的情况下,像 GetLastErrorInfo 这样的静态函数会返回指向 C++ 类的指针(比如说 ErrorInfo),其中包含到达错误信息。 ErrorInfo 保存为线程特定的数据,并包含来自当前线程中最后一次调用的错误信息。如果最后一次 API 调用成功,GetErrorInfo 返回 NULL。
考虑这段代码的例外情况:
尝试 { classPtr->DoSomething(); cout GetData()无一例外都是这样的:
错误码结果; 整数数据; 结果 = classPtr->DoSomething(); 如果(结果!=成功) { cout GetErrorMessage()GetData(data); 如果(结果!=成功) { cout GetErrorMessage()这看起来不太好。类接口很乱:现在每个函数都有 ErrorCode 返回类型。返回值成为输出参数。有没有更好的方法,可以获取错误信息,并保持公共 API 接口干净?
【问题讨论】:
-
您可以使用 boost::tuple 来拥有多种返回类型并避免整个输出参数的事情。但这只是解决真正问题的技巧
-
另外,如何创建解释错误代码并引发异常的内联包装函数。我可以想到两种方法来做到这一点。 1.客户端做包装器(myFunction)。 2.client做myFunction,myFunction是wrapper(internalMyFunction)里面。使用元组和模板元编程通过包装器传递其他返回类型。
-
可能的解决方案是在内部保留最后一个错误,每个方法都会更新它。因此,类方法不需要返回错误。还有一种方法可以访问最后一个错误代码。当然,多线程访问的情况下解决方案会更复杂
-
懒得写真正的答案,不过ideone.com/ONYgz
-
@Eugene - 我正在考虑这个问题。对于多线程,我想使用线程特定的数据(Windows 术语中的 TLS)。
标签: c++ api exception error-handling