如何在DLL导出的接口中处理析构函数 [英] How to handle destructors in DLL exported interfaces

查看:143
本文介绍了如何在DLL导出的接口中处理析构函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从DLL导出类。我阅读了此文章: http:/ /www.codeproject.com/Articles/28969/HowTo-Export-C-classes-from-a-DLL

I'm trying to export a class from a DLL. I read this article on doing so: http://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-from-a-DLL

成熟方法建议,

// Header
class IFoo{
public:
    virtual int getBar() = 0;
}

class Foo: public IFoo {...}

DLLEXPORT IFoo* Create();
DLLEXPRT void Free(IFoo* inst);

//DLL cpp
IFoo* Create(){ return new Foo; }
void Free(IFoo* inst){ delete inst; }

让我感到困惑的是:如果我没有虚拟析构函数,则删除inst 不会调用Foos析构函数,并且可能会泄漏内存。我应该如何处理?这篇文章没有给出答案。

What puzzles me: If I don't have a virtual destructor, then delete inst won't call Foos destructor and may leak memory. How am I supposed to handle that? The article does not give an answer to that.

不可能使用虚拟〜IFoo(){} ,因为这会给IFoo添加一个实现,该实现会引起问题(在有关内联虚拟函数的问题的答案中进行了解释),并且 virtual〜IFoo()= 0; 失败并在未定义符号〜IFoo

Using virtual ~IFoo(){} is not possible, as that adds an implementation to IFoo which causes problems (explained in a answer to a question in the article for an inline virtual function) and virtual ~IFoo() = 0; fails with a linker error on the undefined symbol ~IFoo

安全的方法是什么?释放/释放功能应如何实现?

What is the safe way to go? How should the Free/Release functions be implemented?

推荐答案

首先,让我们注意该问题特定于Visual Studio的处理DLL。 GCC和Clang都有稳定的ABI(Itanium ABI),可以保证使用不同版本编译的库的兼容性。

First of all, let's note that the issue is specific to Visual Studio's handling of DLLs. GCC and Clang both have a stable ABI (Itanium ABI) which guarantees the compatibility of libraries compiled with different versions.

现在,如上所述,您在这里遇到的问题是ABI不稳定,但是ABI的某些部分是稳定的(虚拟表布局),否则提出的策略将无法正常工作。

Now, as mentioned, the issue you face here is ABI instability, however parts of the ABI are stable (the virtual table layout) otherwise the strategy presented would simply not work.

因此,仅具有虚拟析构函数应该起作用。

Therefore, simply having a virtual destructor should work. There will be no name mangling issue because of the call via the virtual table.

此外,请注意,在现代C ++中,返回原始指针是不可以的,但是名称修改会阻止使用智能指针...

Also, note that in modern C++ returning a raw pointer is a no-no, but name mangling prevents the use of a smart pointer...

// Foo.h
class Foo {
public:
    virtual int get() = 0;
    virtual ~Foo();

protected:
    Foo() = default;
    Foo(Foo&&) = default;
    Foo(Foo const&) = default;
    Foo& operator=(Foo) = default;
};

// WARNING: immediately capture this Foo* in a smart pointer,
//          or suffer from memory leak (and worse).
Foo* createFoo(); // factory behind

// Foo.cpp
Foo::~Foo() {} // not inline

这篇关于如何在DLL导出的接口中处理析构函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆