I’ve been on a fun journey down the rabbithole of using TagLib together with Cinder.
I have encountered what appears to be nasty heap corruption using the following code:
TagLib::FileRef tagLibFileRef( "D:/Music/PMPVsTokyo/New2/gibs - VIXEN - Thru Corinnes Eyes.mp3" ); TagLib::String artist = tagLibFileRef.tag()->artist(); std::string test3 = artist.to8Bit( true ); // Works Great - Celebration! std::string test4; test4 = artist.to8Bit( true ); // Debug Assertion Failed! Line 996 - Expression: __acrt_first_black == header
I’m no expert on memory / heap related stuff, but I think the code above should be fine. I inquired with the library makers who reasonably state that the code’s been in wide use since 2013 and so is unlikely to be buggy.
I then tried using TagLib in a completely empty C++ project without Cinder. No crash, the code above works fine.
Running the same code in a completely empty C++ project with Cinder (0.9.2) causes issues.
Things I’ve investigated:
- The heap corruption is only ‘visible’ when compiled in Debug mode. Release mode yields the expected string in both cases. My assumption is that the heap corruption also occurs in Release mode, but given less rigorous checking simply isn’t caught.
- Suspecting perhaps improper Debug/Release library linking I’ve tried linking both with TagLib installed via vcpkg (which I use for lots of other packages with no issues), as well as via a manually built local TagLib version. Same behavior.
- I dynamically link with TagLib (due to LGPL) and the Windows Runtime library my Cinder project is build with is Multi-Threaded, as opposed to Multi-Threaded DLL. I noticed that TagLib was built using the Multi-Threaded DLL, so I tried switching to Multi-Threaded. Same behavior.
And now I’m here… Pretty stumped as to what’s next…?
Open to any suggestions. Also open to someone confirming that the run-time library switching actually doesn’t matter as dynamic linking means both the exe and DLL can have their own run-time library.