|
|
|
|
|
by wahern
1756 days ago
|
|
More relevant to the question of libc, the traditional Windows solution was to require applications to distribute or statically compile their own C runtime. Every release of Visual Studio had its own C runtime. To make matters worse, there was a system C runtime, but most applications didn't link against it, MinGW being a notable exception. AFAIU, this was one of the root culprits for the origin of the notorious DLL Hell. Applications would often crash because libA malloc'd a pointer, which was free'd by libB. That is, there was no shared, global heap. This was a far less obvious pitfall than mixing objects between libA and libB or even libA-v1 and libA-v2. Even if libA-v2 was otherwise backward ABI compatible with libA-v1, if they were built by different versions of Visual Studio you could still end up with heap corruption. Indeed, this could happen if two vendors compiled the exact same source code. If an application install overwrote a library in the shared system folder, boom, applications could begin crashing for no obvious reason. AFAIU, over the years Windows tried to mitigate this with various hacks for detecting cross-heap pointer freeing. But last time I checked their final approach was to guarantee backward compatibility (including backward heap compatibility) for all future Visual Studio C runtimes; ditto for the system C runtime. IOW, Microsoft committed themselves to maintaining a lot of internal runtime magic to preserve binary compatibility across time, which is functionally what glibc has done using version symbols. Of course, it also became less common on Windows to keep DLLs in shared folders. |
|
As far as cross-DLL interop: the usual solution was to avoid the C stdlib altogether, and just use the underlying Win32 API functions to manage memory that has to cross the boundary. Or, in the COM land, every object manages its own heap memory, exposing it via the ABI-standard IUnknown::Release.