Error "Dangling pointer deletion! Class: MouseCursor" when exporting Juce Component from DLL


#1

I’m a Juce newbie, I try to write sample app like this:

  • Implement DLL to export a GUI (Juce Component).
  • The app will get Juce component from DLL then add it into MainContentComponent.
    However, when I debug the app, move mouse cursor over the Juce component which exported from DLL, I got the error
    "*** Dangling pointer deletion! Class: MouseCursor
    JUCE Assertion failure in juce_leakedobjectdetector.h:71"

1. Here are the codes in DLL:
- TuningGuiInterface.h

// The interface used to communicate between MainApp and DLL
class GuiModuleInterface
{

public:
virtual Component* getGuiModuleData() = 0;
};

**- TuningGuiInterface.cpp**
#include "TuningGuiInterface.h"
#include "GuiComponent.h"

#ifdef GUI_LIBRARY_EXPORTS
#define GUI_DLL_API __declspec(dllexport)
#else
#define GUI_DLL_API __declspec(dllimport)
#endif

// Implement the DLL interface
class GuiModuleImpl : public GuiModuleInterface
{

private:
Component* guiComponent;
public:
virtual Component* getGuiModuleData() override;
};

Component* GuiModuleImpl::getGuiModuleData()
{
guiComponent = new GuiComponent(message);
return guiComponent;
}

// Export method to get DLL instance
extern “C” GUI_DLL_API GuiModuleInterface* GetDLLInterface()
{
static GuiModuleImpl* gGuiModule = new GuiModuleImpl();
return gGuiModule;
}

- GuiComponent.h
class GuiComponent : public Component
{
public:
GuiComponent();
~GuiComponent();

void paint (Graphics&);
void resized();

private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GuiComponent)
};

- GuiComponent.cpp
#include "GuiComponent.h"

GuiComponent::GuiComponent()
{
setSize (100, 100);
}

GuiComponent::~GuiComponent()
{
}

void GuiComponent::paint (Graphics& g)
{
g.fillAll (Colour (0xff001F36));
g.setFont (Font (16.0f));
g.setColour (Colours::white);
g.drawText (“This is message from DLL”, getLocalBounds(), Justification::centred, true);
}

void GuiComponent::resized()
{
// This is called when the MainContentComponent is resized.
// If you add any child components, this is where you should
// update their positions.
}

2. And in the App, we have:
- MainComponent.h
#include “…/JuceLibraryCode/JuceHeader.h”
#include “TuningGuiInterface.h”
#include “GuiDllLoader.h”

class MainContentComponent : public Component
{
public:
MainContentComponent();
~MainContentComponent();

void paint (Graphics&);
void resized();

private:

// Define variables to load DLL, and store DLL GUI instance
TGuiDllLoader<GuiModuleInterface> dll_loader;
GuiModuleInterface* guiDLLInterface;

  JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent)

};

- MainComponent.cpp

#include "MainComponent.h"

MainContentComponent::MainContentComponent()
{
// Load the TuningGui_v1.dll, call method GetDLLInterface() to return DLL instance
dll_loader = TGuiDllLoader(“TuningGui_v1”, “GetDLLInterface”);
guiDLLInterface = dll_loader.GetInterface();
addAndMakeVisible(guiDLLInterface->getGuiModuleData());
setSize(600, 400);
}

MainContentComponent::~MainContentComponent()
{
// Invoke DLL to release its variables
guiDLLInterface->releaseGuiObject();
dll_loader.UnloadDLL();
}

void MainContentComponent::paint (Graphics& g)
{
g.fillAll (Colour (0xff001F36));
g.setFont (Font (16.0f));
g.setColour(Colours::white);
g.drawText(“MainContentComponent”, getLocalBounds(), Justification::centred, true);
}

void MainContentComponent::resized()
{
// This is called when the MainContentComponent is resized.
// If you add any child components, this is where you should
// update their positions.
}

And here are the trace of Call Stack:
TuningApp.exe!juce::LeakedObjectDetectorjuce::MouseCursor::~LeakedObjectDetectorjuce::MouseCursor() Line 71 C++
TuningApp.exe!juce::MouseCursor::~MouseCursor() Line 160 C++
TuningApp.exe!juce::MouseInputSourceInternal::revealCursor(bool forcedUpdate) Line 472 C++
TuningApp.exe!juce::MouseInputSourceInternal::setScreenPos(juce::Point newScreenPos, juce::Time time, const bool forceUpdate) Line 289 C++
TuningApp.exe!juce::MouseInputSourceInternal::handleEvent(juce::ComponentPeer & newPeer, juce::Point positionWithinPeer, juce::Time time, const juce::ModifierKeys newMods, float newPressure) Line 320 C++
TuningApp.exe!juce::MouseInputSource::handleEvent(juce::ComponentPeer & peer, juce::Point pos, int64 time, juce::ModifierKeys mods, float pressure) Line 582 C++
TuningApp.exe!juce::ComponentPeer::handleMouseEvent(int touchIndex, juce::Point pos, juce::ModifierKeys newMods, float newPressure, int64 time) Line 91 C++
TuningApp.exe!juce::HWNDComponentPeer::doMouseEvent(juce::Point position, float pressure) Line 1676 C++
TuningApp.exe!juce::HWNDComponentPeer::doMouseMove(juce::Point position, bool isMouseDownEvent) Line 1780 C++
TuningApp.exe!juce::HWNDComponentPeer::peerWindowProc(HWND
* h, unsigned int message, unsigned int wParam, long lParam) Line 2468 C++

TuningApp.exe!juce::HWNDComponentPeer::windowProc(HWND
* h, unsigned int message, unsigned int wParam, long lParam) Line 2401 C++

_[External Code] _
_[Frames below may be incorrect and/or missing, no symbols loaded for user32.dll] _
TuningApp.exe!juce::MessageManager::dispatchNextMessageOnSystemQueue(bool returnIfNoPendingMessages) Line 147 C++
TuningApp.exe!juce::MessageManager::runDispatchLoop() Line 130 C++
TuningApp.exe!juce::JUCEApplicationBase::main() Line 244 C++

I don’t know the reason why it called MouseCursor::~MouseCursor() when I moved the mouse cursor over the Juce component that exported from DLL.

It took me few days but I still do not figure out the root cause. Please help if you experienced about this. Thanks in advance !