Confusion around File Chooser

I’m attempting to write a system that allows me to open a file dialogue to choose and load data within JSON files. I’m running into a brick wall however where the file chooser seems to be refusing to cooperate. I haven’t been able to find satisfactory documentation on how to get this working.

My code is as follows:

juce::String defaultPath = juce::File::getSpecialLocation(juce::File::SpecialLocationType::userApplicationDataDirectory).getFullPathName();
juce::File defaultDirectory = juce::File(defaultPath);
_chooser = std::make_unique<juce::FileChooser>("Choose file", defaultDirectory, "*.json");
// Code stops working here ^

int chooserFlags = juce::FileBrowserComponent::openMode
    | juce::FileBrowserComponent::canSelectFiles;

_chooser->launchAsync(chooserFlags, [this](const juce::FileChooser& fc)
{
    auto file = fc.getResult();
     if (file != juce::File{}) 
    {
        // Do Stuff
    }
});

Execution is breaking, and an exception is being thrown on like 616 of utility, shown below.

// FUNCTION TEMPLATE exchange
template <class _Ty, class _Other = _Ty>
_CONSTEXPR20 _Ty exchange(_Ty& _Val, _Other&& _New_val) noexcept(
    conjunction_v<is_nothrow_move_constructible<_Ty>, is_nothrow_assignable<_Ty&, _Other>>) /* strengthened */ {
    // assign _New_val to _Val, return previous _Val
    _Ty _Old_val = static_cast<_Ty&&>(_Val); //  <--- Exception thrown here
    _Val         = static_cast<_Other&&>(_New_val);
    return _Old_val;
}

Any suggestions on how to resolve this issue? I am pretty thoroughly confused by this.

Have you tried the built-in examples, e.g. the DialogsDemo? If so, does the native filechooser open correctly there?

There’s not enough information in the question to diagnose the problem. It would be useful to see the entire call stack at the point of the crash, although that still may not include enough information.

You could also try building with Address Sanitizer (instructions here) and seeing whether that gives you any additional details.

The DialogsDemo seems to be working as it should.
I’ve tried moving the code from there to my own project, and I still throw an exception in the exact same place.

Call stack is as follows: Admittedly I can’t make heads or tails of it.
I don’t think I can use Address Sanitizer, given I’m on Windows.

|>|MainWindowTutorial.exe!std::exchange<juce::FileChooser *,juce::FileChooser * &>(juce::FileChooser * & _Val, juce::FileChooser * & _New_val) Line 616|C++|
|---|---|---|
| |MainWindowTutorial.exe!std::unique_ptr<juce::FileChooser,std::default_delete<juce::FileChooser>>::reset(juce::FileChooser * _Ptr) Line 3263|C++|
| |MainWindowTutorial.exe!FileChooserJSONHandler::readDataFromJSONFile() Line 53|C++|
| |MainWindowTutorial.exe!NodeMCUPatternProgrammer::loadPatternFromFile() Line 280|C++|
| |MainWindowTutorial.exe!NodeMCUPatternProgrammer::{ctor}::__l2::<lambda>() Line 31|C++|
| |[External Code]||
| |MainWindowTutorial.exe!juce::Button::sendClickMessage(const juce::ModifierKeys & modifiers) Line 425|C++|
| |MainWindowTutorial.exe!juce::Button::internalClickCallback(const juce::ModifierKeys & modifiers) Line 369|C++|
| |MainWindowTutorial.exe!juce::Button::mouseUp(const juce::MouseEvent & e) Line 492|C++|
| |MainWindowTutorial.exe!juce::Component::internalMouseUp(juce::MouseInputSource source, const juce::PointerState & relativePointerState, juce::Time time, const juce::ModifierKeys oldModifiers) Line 2577|C++|
| |MainWindowTutorial.exe!juce::MouseInputSourceInternal::sendMouseUp(juce::Component & comp, const juce::PointerState & pointerState, juce::Time time, juce::ModifierKeys oldMods) Line 144|C++|
| |MainWindowTutorial.exe!juce::MouseInputSourceInternal::setButtons(const juce::PointerState & pointerState, juce::Time time, juce::ModifierKeys newButtonState) Line 187|C++|
| |MainWindowTutorial.exe!juce::MouseInputSourceInternal::handleEvent(juce::ComponentPeer & newPeer, juce::Point<float> positionWithinPeer, juce::Time time, const juce::ModifierKeys newMods, float newPressure, float newOrientation, juce::PenDetails pen) Line 312|C++|
| |MainWindowTutorial.exe!juce::MouseInputSource::handleEvent(juce::ComponentPeer & peer, juce::Point<float> pos, __int64 time, juce::ModifierKeys mods, float pressure, float orientation, const juce::PenDetails & penDetails) Line 610|C++|
| |MainWindowTutorial.exe!juce::ComponentPeer::handleMouseEvent(juce::MouseInputSource::InputSourceType type, juce::Point<float> pos, juce::ModifierKeys newMods, float newPressure, float newOrientation, __int64 time, juce::PenDetails pen, int touchIndex) Line 90|C++|
| |MainWindowTutorial.exe!juce::HWNDComponentPeer::doMouseEvent(juce::Point<float> position, float pressure, float orientation, juce::ModifierKeys mods) Line 2886|C++|
| |MainWindowTutorial.exe!juce::HWNDComponentPeer::doMouseUp(juce::Point<float> position, const unsigned __int64 wParam) Line 3063|C++|
| |MainWindowTutorial.exe!juce::HWNDComponentPeer::peerWindowProc(HWND__ * h, unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 3967|C++|
| |MainWindowTutorial.exe!juce::HWNDComponentPeer::windowProc(HWND__ * h, unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 3862|C++|
| |[External Code]||
| |MainWindowTutorial.exe!juce::InternalMessageQueue::dispatchNextMessage(bool returnIfNoPendingMessages) Line 149|C++|
| |MainWindowTutorial.exe!juce::dispatchNextMessageOnSystemQueue(bool returnIfNoPendingMessages) Line 266|C++|
| |MainWindowTutorial.exe!juce::MessageManager::runDispatchLoop() Line 109|C++|
| |MainWindowTutorial.exe!juce::JUCEApplicationBase::main() Line 266|C++|
| |MainWindowTutorial.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, char * __formal, int __formal) Line 105|C++|
| |[External Code]||

After further investigation, the error seems to be thrown in this block of code belonging to the file simply labeled memory.

    void reset(pointer _Ptr = nullptr) noexcept {
        pointer _Old = _STD exchange(_Mypair._Myval2, _Ptr); // Exception thrown by this line
        if (_Old) {
            _Mypair._Get_first()(_Old);
        }
    }

I have resolved the issue, and I am both happy and rather chagrined to admit that I simply forgot to instantiate my wrapper class around the FileChooser.

Problem solved, and I feel silly.

1 Like