xz/windows/liblzma-crt-mixing.txt

71 lines
2.8 KiB
Plaintext

liblzma.dll and mixing C runtimes (CRTs)
----------------------------------------
If possible, liblzma.dll should be linked against the same CRT
(MSVCRT or UCRT) as the application calling the liblzma functions.
When this isn't possible, liblzma.dll will still work but there
are a few API functions that need extra care.
Each CRT has its own memory allocator, stdio FILE implementation,
mapping of file descriptors from _open() to Windows' HANDLEs, and
so on. Mixing CRTs is a problem if, for example, one library calls
fopen() and then passes the resulting FILE* to a second library and
these two libraries use different CRTs. liblzma doesn't expose FILE
pointers or file descriptors in the API but the problem can occur
with memory allocation with a few specific functions.
The most commonly-used API functions in liblzma are such that both
memory allocation and deallocation is done internally by liblzma,
thus most applications won't have any problems with mixing CRTs
with liblzma.dll. The following API functions are the exception:
lzma/block.h:
lzma_block_header_decode
lzma/filter.h:
lzma_filters_copy
lzma_filters_free
lzma_properties_decode
lzma_filter_flags_decode
lzma_str_to_filters
lzma_str_from_filters
lzma_str_list_filters
Excluding lzma_filters_free(), the above functions allocate memory
and leave it to the caller to free it. lzma_filters_free() frees
memory given to it, and that memory may have been allocated outside
of liblzma.
For example, if application calls lzma_str_list_filters(&ptr, ...)
and then uses free(ptr), something bad (memory corruption, crash)
will happen if the application and liblzma.dll aren't using the
same CRT. This can be worked around with a few lines of extra code.
All these functions (and many others too) take a pointer to
lzma_allocator structure as an argument. Typically it is set to
NULL to let liblzma use malloc() and free() (and also calloc()
as it is faster than malloc() + memset()). A custom lzma_allocator
can be used to wrap malloc() and free() from application's CRT:
static void * LZMA_API_CALL
my_alloc(void *opaque, size_t nmemb, size_t size)
{
// liblzma guarantees that this won't overflow.
return malloc(nmemb * size);
}
static void LZMA_API_CALL
my_free(void *opaque, void *ptr)
{
free(ptr);
}
static const lzma_allocator allocator
= { &my_alloc, &my_free, NULL };
By passing &allocator to the problematic functions, CRT mixing
should not cause any problems. There is no need to use &allocator
with functions other than those listed above.