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.