msdfgen
msdfgen copied to clipboard
Problems with memory using msdfgen DLL with Staticly linked Runtime Library (/MT)
We're using msdfgen-core in our project. When building it as a dll (msdfgen-cored.dll) we mistakenly used (/MT) flag which uses the static version of the runtime library in the msdfgen dll; however that led me to find some issues with msdfgen I wanted to share:
If our application (exe) or some other dll is calling msdfgen function it might call it with a different version of the runtime library and this mismatch of C++ runtime libraries can be real problematic (for example changes to std::vector
implementation and how it works with memory, esp with usages of vectors in msdfgen code).
This means that our allocations/deallocation, construction/deconstruction, new/deletes must all happen in a single module to avoid working with pointers/vector/memory allocated by other module which can be bug prune. (debug_heap asserts in runtime helps us avoid it)
With all that in mind here are the issues:
- msdfgen classes have constructors implemented in cpp (eventually in dll) but the destructors are implicit in header
for example Shape.h if used through a /MT built dll, it will construct the
std::vector<Contour> contours;
using it's runtime and it will destruct it in the caller module in~Shape
This happens because we're exporting using Module Definition Files (.def
) which doesn't export classes default destructors and we're not using dll_export/import on the whole class.
using class MSDFGEN_PUBLIC Shape {
on the whole class is a fix.
Alternatively: implement deconstructors explicitly in cpp and add to .def
- inconsistency and unclear interface: in EdgeHolder::16
we can pass in any edge segment pointer that we have "new"ed on the caller module but the delete is happening inside msdfgen dll in
EdgeHolder::~EdgeHolder
. This will cause confusion to the user to attemp creating Linear/Quad/Cubic segments and pass by pointer instead of usingEdgeSegment::create
functions.
Suggestion: make this trivial constructor protected/private to protect against incorrect usage
Let me know about your mindset on this and whether you'd like me to open a PR to fix these.
Additional Resources:
- https://learn.microsoft.com/en-us/cpp/build/reference/md-mt-ld-use-run-time-library?view=msvc-170