首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Dll安全异常处理

Dll安全异常处理
EN

Stack Overflow用户
提问于 2017-09-26 04:29:55
回答 1查看 509关注 0票数 0

我正在考虑在我正在编写的一些库中使用异常处理。该代码库最终可以在多个dlls中实现。我知道跨dlls使用异常处理不是一个好主意--然而,这样做安全吗?

代码语言:javascript
复制
class IDllSafeException
{
public:
    virtual void AddRef() = 0;
    virtual void Release() = 0;
    virtual int GetErrorCode() const = 0;
    virtual const char * What() const = 0;
};

假设这是一种有效的方法,我真的希望通过值来捕获,而不是指针。这样,我就可以有一个自动调用Release()的包装类。

因此...

代码语言:javascript
复制
template <typename T>
class SafeExceptionT
{
public:
    SafeExceptionT(T *);            
    SafeExceptionT(SafeExceptionT &);
    SafeExceptionT & operator=(SafeExceptionT &);
    ~SafeExceptionT();

    int GetErrorCode() const;
    const char * What() const;
private:
    T * m_pException;
};

typedef SafeExceptionT<IDllSafeException> SafeException;

作为模板意味着所有catch块都将生成自己的布局,并在析构函数中调用can m_pException->Release() (复制发生时使用AddRef() )。我还可以根据需要实现不同类型的异常。

我的catch代码块看起来就像这样...

代码语言:javascript
复制
try
{
    ThrowSomething();
}
catch(SafeException except)
{       
    const char * psz = except.What();
    int nErrorCode = except.GetErrorCode();
}

..。

代码语言:javascript
复制
void ThrowSomething()
{   
    // Concrete implementation omitted for brevity
    throw new DllSafeException(1, "something went wrong");
}

我本以为这会起作用,但是我的异常处理程序没有被捕获,即使我有一个非显式的SafeException构造函数。

然而,我似乎只能通过指针来捕获...

代码语言:javascript
复制
try
{
    ThrowSomething();
}
catch(SafeException except)
{       
    /// IGNORED!
    ...
}
catch(IDllSafeException * pExcept)
{       
    // CAUGHT BY POINTER but we now have to micro-manage.
    const char * psz = pExcept->What();
    int nErrorCode = pExcept->GetErrorCode();
    pExcept->Release();
}

对于如何在异常处理程序中匹配类型,是否有特殊的规则?

EN

回答 1

Stack Overflow用户

发布于 2017-09-26 19:25:43

如果任何人感兴趣,上面的代码通过使用抽象基类和依赖于编译器之间一致的vtable布局,确实成功地绕过了dll边界异常问题。

我在VS2008和VS2017上进行了测试。我在每个环境中构建了一个dll,每个环境中都有一个控制台应用程序。dll引发异常,exception类在内部聚合一个对象,以确保发生堆分配。

我还在不同的dll/控制台应用程序之间混合和匹配了C-runtime的版本(静态和dll)。我可以成功地引发/捕获跨dll划分的异常。

不出所料,vtable布局确保了delete/~tor在正确的二进制文件中执行。

唯一需要注意的是,您必须通过抽象接口抛出。这也意味着确保您手动调用pEx->Release。我知道这不是很好,但我仍然不知道为什么我的另一个类不能通过它的非显式构造函数来捕获异常。

VS2008 Example Debug Session

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46413673

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档