c++ - 尝试从 DLL 加载的派生类实例访问基类 vector 成员时程序崩溃

标签 c++ visual-c++ inheritance dll

我遇到了奇怪的崩溃。我试图将我的应用程序(基于 MFC,在 VS2005 中开发)的各个模块分离到 DLL 中。以下是我如何实现它的骨架代码:

在通用头文件中(例如base.h):

class Base {
    vector<message> messages;
    ...
    ...
};

在DLL源代码的头文件中(比如class.h):

class Derived : public Base {
private:
    int hoo();
    ...
public:
    void foo();
    int goo();
    ...
};

extern "C" __declspec (dllexport) Derived* CreateDerived();

在类.cpp中

 Derived* CreateDerived()
 {
    return new Derived;
 }

在主应用程序代码的文件中:

#include "base.h"
#include "class.h"

typedef Derived* (*DerivedCreator)();
...
...

void LoadDll()
{
    //DLL Load Code...
    ...
    ...

    DerivedCreator creator = reinterpret_cast<DerivedCreator>(::GetProcAddress(dllHandle, "CreateDerived"));

    Derived* pDerived = creator();

    pDerived->messages.push_back(message("xyz"));//Crashes here...
}

问题是当我尝试访问基类的 vector 成员时代码崩溃了。这只发生在 Release模式下。它在 Debug模式下工作正常。当我在 Release模式下从 Visual Studio 执行它时收到的错误消息是:

“Microsoft Visual Studio C 运行时库在 Samsung SSD Magician.exe 中检测到 fatal error 。

按“Break”调试程序或按“Continue”终止程序。”

但是当我直接执行发布二进制文件并将调试器附加到它时,我收到了访问冲突。此时,如果我检查调试器中的 vector ,它会显示其中的 6 位条目,但没有一个是可读的。我可以在派生指针中看到基类其余成员的正确值。

任何帮助将不胜感激。

最佳答案

跨 DLL 边界传递 STL 容器是危险的。 原因是每个模块(主应用程序和 DLL)都有自己的堆实例。如果您在 DLL 上下文中分配动态内存,然后将指针传递给应用程序并在应用程序上下文中释放该内存,则会导致堆损坏。

这正是您的示例中发生的情况。

Derived* pDerived = creator();

CreateDerived 被调用。

 Derived* CreateDerived()
 {
    return new Derived;
 }

new Derived 在 DLL 堆中分配内存。

pDerived->messages.push_back(message("xyz"));

push_back内部,为Base::messages分配了额外的内存,并且该分配是在应用程序堆上完成的。崩溃!

结论是,您需要重新考虑 DLL 接口(interface),以便仅在 DLL 内部对 vector 执行所有操作。

关于c++ - 尝试从 DLL 加载的派生类实例访问基类 vector 成员时程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10244770/

相关文章:

c++ - 函数重载的可见性在基类和派生类之间分离

c++ - 有没有比添加 0.5f 和截断转换更直接的方法来将 float 转换为 int 并进行舍入?

c++ - 递归地打印一个类内部的链表c++

c++ - 反转按位左移和或赋值

visual-c++ - 如何从 mfc 应用程序调用 IE 或任何其他浏览器?

visual-c++ - MFC 是否仍用于新开发(具有任何 Material 量)?

c++ - 在继承中访问私有(private)成员

perl - Perl 中的 DBIx 和继承

python - setfill 和 setw python 等效?

c++ - 将 OpenSSL 静态库添加到 vc++ 项目