pocoproject / poco

The POCO C++ Libraries are powerful cross-platform C++ libraries for building network- and internet-based applications that run on desktop, server, mobile, IoT, and embedded systems.
https://pocoproject.org
Other
8.04k stars 2.11k forks source link

Poco::ClassLoader will crashed when DLL and EXE not use MD/MDd RunTime-Library #4549

Open siren186 opened 1 month ago

siren186 commented 1 month ago

Describe the bug Poco::Manifest class has STL member, It will crash if DLL and EXE use different Run-Time Library (MT/MD)

To Reproduce Build options: VS2019 + debugstaticmt + x64 ( It must be in debug mode and not MD if you wanna see the crash message box)

EXE code

#include "DLLTest/AbstractPlugin.h"

int wmain(int argc, wchar_t** argv)
{
    Poco::ClassLoader<AbstractPlugin> loader;
    loader.loadLibrary("Test.dll");
    AbstractPlugin* pPluginA = loader.create("PluginA");
    AbstractPlugin* pPluginB = loader.create("PluginB");

    loader.classFor("PluginA").autoDelete(pPluginA);
    delete pPluginB;
    loader.unloadLibrary("Test.dll");
}

DLL code

class AbstractPlugin
{
public:
    virtual ~AbstractPlugin() {};
    virtual void foo() const = 0;
};

class PluginA : public AbstractPlugin
{
public:
    virtual void foo() const override
    {
    }
};

class PluginB : public AbstractPlugin
{
public:
    virtual void foo() const override
    {
    }
};

POCO_BEGIN_MANIFEST(AbstractPlugin)
POCO_EXPORT_CLASS(PluginA)
POCO_EXPORT_CLASS(PluginB)
POCO_END_MANIFEST

Screenshots PocoCrash

Please add relevant environment information:

obiltschnig commented 1 month ago

You are not supposed to use different runtime libraries in your main application and your plugins.

siren186 commented 1 month ago

If I use MT to build DLL and EXE, it will crash, Because the STL container are malloc in DLL, but free in EXE

obiltschnig commented 1 month ago

That's an unfortunate side effect of using MT with DLLs. Nothing we can do about it.

siren186 commented 1 month ago

What about hiding the implementation of Poco::Manifest::insert and Poco::Manifest::clear, to make sure who new, who delete, then it will not crash anymore.

andrewauclair commented 1 month ago

What about hiding the implementation of Poco::Manifest::insert and Poco::Manifest::clear, to make sure who new, who delete, then it will not crash anymore.

That can't be done. Manifest is a templated class.

siren186 commented 1 month ago

That can't be done. Manifest is a templated class.

I wanna use POCO with CEF3 (https://github.com/chromiumembedded/cef), But my CEF3 applications are building with MT. I am using use my own plugin loader (https://github.com/siren186/z_com), It can work with different MT/MDs. Now I wanna use POCO to instead, But it seems impossible