lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Am 21.09.2016 um 01:33 schrieb Thijs Schreijer:

On 20 Sep 2016, at 15:12, Christian N. <cn00@gmx.at> wrote:
Of course if a binary was compiled against CRT A but is dynamically linked against CRT B then all bets are off.

But normally incompatible runtimes will have different DLL names (msvcr110.dll, msvcr120.dll, etc.). Thus when you compile a DLL against CRT A and your executable against CRT B then both CRTs will be loaded at runtime and the DLL and the main executable will both use their own ones independently.

‒ Christian


This is simply not true, read up on the MSDN link I send earlier in the thread, where Microsoft discusses the potential problems of using multiple runtime (don’t take my word for it, better take theirs, they wrote the stuff).

Repeating; mixing runtime ‘seems’ to work, until it doesn’t. You’ll get sporadic and hard to trace crashes. Search the archives, plenty of others went before you…

Thijs



First, even though I argue that in the case of Lua, there is no problem with mixed CRTs, I do so mostly on theoretical grounds (though I did have success mixing a small MSVC 2015 executable and the MSVC 2013 Lua DLL). I do not recommend mixing CRTs if at all possible.

But I have read your MSDN link (https://msdn.microsoft.com/en-us/library/ms235460.aspx) and if anything, it seems to support my arguments:

> Each copy of the CRT library has a separate and distinct state.

In detail:

> When you pass C Run-time (CRT) objects such as file handles, locales,
> and environment variables into or out of a DLL unexpected behavior
> can occur if the DLL, as well as the files calling into the DLL, use
> different copies of the CRT libraries.

Since Lua 5.3, there is indeed a (single) place where this happens: A luaL_Stream has a FILE* member. Also communicating with Lua via environment variables and locales may or may not be possible across CRTs (I think that was already mentioned in this thread). That alone is already good reason not to mix CRTs.

> A related problem can occur when you allocate memory (either
> explicitly with new or malloc, or implicitly with strdup,
> strstreambuf::str, and so on) and then pass a pointer across a DLL
> boundary to be freed.

This is not the case for Lua thanks to the usage of a single lua_Alloc function that manages all memory (but beware calling lua_setallocf!).

If you interpret the "if" in the following sentence as "if and only if":

> If you design your DLL so that it passes CRT objects across the
> boundary or allocates memory and expects it to be freed outside the
> DLL, you restrict the DLL users to use the same copy of the CRT
> library as the DLL.

then this is even documented as working. Which would make sense when you consider things like ActiveX, COM, OLE which are binary standards (but more or less a superset of a library-less C ABI) designed to work even across language boundaries. E.g. I can see in my running explorer.exe:
- ucrtbase.dll (VC 14)
- msvcr120.dll
- msvcr90.dll
- msvcrt.dll (this one seems to be loaded into every process)

Shell plugins and the like that work across different windows versions would not be possible if only one CRT could be loaded per process. I thus conclude that a CRT may not assume that it is the only one in a process (on Windows).


Tangetially related: With the ucrtbase.dll since Windows 10 / VS 2015, the operating system becomes a CRT delivery channel again (cf. the oldnewthing blog article mentioned previously in this thread). This CRT is announced to be stable across major VS versions (https://blogs.msdn.microsoft.com/vcblog/2015/03/03/introducing-the-universal-crt/) and will thus hopefully tame the Windows CRT jungle.

‒ Christian