API设计和错误处理

API设计和错误处理

本文介绍了C ++ API设计和错误处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要编写C ++ API,它包含几个从Dll公开的导出的C ++类,使用.lib文件(MSVC)。从对我的另一个问题的答案,我明白,导出的类方法不能使用异常,如果C ++ API是在一个VC ++版本(假设2010),而客户端代码是写在另一个VC ++版本的情况下。由于异常不能作为公共API接口的一部分,我正在寻找另一个错误处理策略。我的限制:我不想使用COM,丰富的错误代码系统(如HRESULT)对我来说是不够的。我想有异常类的包含错误代码,错误消息和任何其他信息,我需要。此外,我不想为每个VC ++版本单独构建。

I need to write C++ API, which consists of several exported C++ classes exposed from Dll, using .lib files (MSVC). From the answer to my another question I understand, that exported class methods cannot use exceptions, in the case if C++ API is built in one VC++ version (let's say 2010), and client code is written in another VC++ version. Since exceptions cannot be a part of public API interface, I am looking for another error handling strategy. My restrictions: I don't want to use COM, and rich error code system (like HRESULT) is not enough for me. I want to have exception-like class which contains error code, error message and any other information that I need. Also, I don't want to make separate build for every VC++ version.

我目前的方法如下。每个公共类方法返回枚举值(如ErrorCode)。在方法失败的情况下,像GetLastErrorInfo一样的静态函数返回指向C ++类(我们说ErrorInfo)的指针,它包含到达错误信息。 ErrorInfo保留为线程特定的数据,并包含当前线程中最后一次调用的错误信息。如果最后一个API调用成功,GetErrorInfo返回NULL。

My current approach is the following. Every public class method returns enumerated value (like ErrorCode). In the case the method fails, static function like GetLastErrorInfo returns the pointer to C++ class (let's say ErrorInfo), which contains reach error information. ErrorInfo is kept as thread-specific data, and contains error information from the last call in the current thread. If last API call succeeded, GetErrorInfo returns NULL.

请考虑以下代码:


try
{
    classPtr->DoSomething();
    cout << classPtr->GetData() << endl;
}
catch(const MyException& ex)
{
    cout << ex.GetErrorMessage() << endl;
    return;
}

没有例外,它看起来像这样:

Without exceptions, it looks like this:


ErrorCode result;
int data;
result = classPtr->DoSomething();
if ( result != Success )
{
    cout << MyClass::GetLastErrorInfo()->GetErrorMessage() << endl;
    return;
}
result = classPtr->GetData(data);
if ( result != Success )
{
    cout << MyClass::GetLastErrorInfo()->GetErrorMessage() << endl;
    return;
}
cout << data << endl;

这看起来不太好。类接口是凌乱:每个函数现在有ErrorCode返回类型。返回值成为输出参数。是否有更好的方法,允许有到达错误信息,并保持干净的公共API接口?

This doesn't look good. Class interface is messy: every function now has ErrorCode return type. Return values become output parameters. Is there better approach, that allows to have reach error information, and to keep clean public API interface?

推荐答案

一个简单的解决方案。唯一的限制是异常不能跨越模块边界。客户端代码本身没有问题抛出异常。因此,在头文件中提供一个抛出丰富异常的内联函数,例如CheckReturn()。

You are possibly overlooking a simple solution. The only restriction is that an exception cannot cross a module boundary. There is no problem with the client code itself throwing an exception. So provide an inline function in the header, say CheckReturn(), that throws the rich exception.

有关灵感,请查看COM IErrorInfo接口及其相关的。他们解决完全相同的问题。还要注意MSVC中可用的#import指令,它会自动生成调用该函数的小包装函数,并在故障返回值上抛出异常。但是你不想使用COM,所以不能直接使用。

For inspiration, look at the COM IErrorInfo interface and its associated _com_error class. They solve the exact same problem. Also note the #import directive available in MSVC, it auto-generates the small wrapper functions that make the call and throw the exception on a failure return value. But you don't want to use COM so that's not directly usable.

这篇关于C ++ API设计和错误处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 03:49