Hi Jules,
(All the demonstration codes below are trivial and straightforward. Dylib and GUI app projects created by Introjucer.)
I created a trivial Component subclass and build it as a .dylib on Mac. There are C style constructor and destructor helper functions. Then I load and use this Component class in a main desktop GUI app. It works correctly but several leaking assertion failures are met on every quit.
The header file:
class LibComponent : public Component
{
public:
LibComponent();
~LibComponent();
void paint (Graphics& g);
void resized ();
};
extern "C" LibComponent *NewLibComponentHelper();
typedef LibComponent *LibComponent_Constructor_Helper();
extern "C" void DeleteLibComponentHelper(LibComponent*);
typedef void LibComponent_Destructor_Helper(LibComponent*);
The src file:
#include "LibComponent.h"
LibComponent::LibComponent()
{
std::cout << "lib Component construct\n";
setSize(30, 20);
}
LibComponent::~LibComponent()
{
std::cout << "lib Component destructor\n";
deleteAllChildren();
}
void LibComponent::paint(Graphics& g)
{
std::cout << "lib Component paint\n";
g.fillAll(Colours::aqua);
}
void LibComponent::resized()
{
std::cout << "lib Component resized\n";
}
__attribute__((visibility("default")))
LibComponent* NewLibComponentHelper() {
return new LibComponent();
}
__attribute__((visibility("default")))
void DeleteLibComponentHelper(LibComponent* libC) {
if (libC) {
delete libC;
libC = NULL;
std::cout << "libC nulled\n";
}
}
The host app codes (main component):
//==============================================================================
MainContentComponent::MainContentComponent()
{
libC = nullptr;
bool isOpened = testLib.open("/Users/shaoduo/Desktop/TestASLibJuce/Builds/MacOSX/build/Debug/TestASLibJuce.dylib");
if (!isOpened) {
std::cout << "open lib failed\n";
}
LibComponent_Constructor_Helper *libCompConstructor = (LibComponent_Constructor_Helper*)testLib.getFunction("NewLibComponentHelper");
if (!libCompConstructor) {
std::cout << "open func constructor failed\n";
}
libCompDestructor = (LibComponent_Destructor_Helper*)testLib.getFunction("DeleteLibComponentHelper");
if (!libCompDestructor) {
std::cout << "open func destructor failed\n";
}
libC = libCompConstructor();
if (libC) {
addAndMakeVisible(libC);
}
setSize (500, 400);
}
MainContentComponent::~MainContentComponent()
{
if (libC) {
removeChildComponent(libC);
libCompDestructor(libC);
}
libCompDestructor = NULL;
testLib.close();
}
I think I followed the routine of using a dylib at run time.
The codes runs correct and the component from the dylib can be correctly seen in the app.
But on quit, I got bunch of leaked object assertion
*** Leaked objects detected: 1 instance(s) of class DisplaySettingsChangeCallback
JUCE Assertion failure in juce_LeakedObjectDetector.h:95
*** Leaked objects detected: 1 instance(s) of class Desktop
JUCE Assertion failure in juce_LeakedObjectDetector.h:95
*** Leaked objects detected: 1 instance(s) of class ComponentAnimator
JUCE Assertion failure in juce_LeakedObjectDetector.h:95
*** Leaked objects detected: 1 instance(s) of class OwnedArray
JUCE Assertion failure in juce_LeakedObjectDetector.h:95
*** Leaked objects detected: 1 instance(s) of class MouseInputSource
JUCE Assertion failure in juce_LeakedObjectDetector.h:95
*** Leaked objects detected: 1 instance(s) of class MouseInputSourceInternal
JUCE Assertion failure in juce_LeakedObjectDetector.h:95
*** Leaked objects detected: 1 instance(s) of class OwnedArray
JUCE Assertion failure in juce_LeakedObjectDetector.h:95
*** Leaked objects detected: 3 instance(s) of class AsyncUpdater
JUCE Assertion failure in juce_LeakedObjectDetector.h:95
*** Leaked objects detected: 1 instance(s) of class MessageManager
JUCE Assertion failure in juce_LeakedObjectDetector.h:95
I currently have no idea how to find the cause down there. If I get rid of the dylib and compile the component subclass in the GUI app, there won't be any issue (of course...). But with a dylib, it gives leaking asserstion failures on quit. Any thoughts on this or how to debug this?
Thanks a lot.