summaryrefslogtreecommitdiffstats
path: root/windows/liblzma-crt-mixing.txt
diff options
context:
space:
mode:
Diffstat (limited to 'windows/liblzma-crt-mixing.txt')
-rw-r--r--windows/liblzma-crt-mixing.txt70
1 files changed, 70 insertions, 0 deletions
diff --git a/windows/liblzma-crt-mixing.txt b/windows/liblzma-crt-mixing.txt
new file mode 100644
index 0000000..4ef2f8a
--- /dev/null
+++ b/windows/liblzma-crt-mixing.txt
@@ -0,0 +1,70 @@
+
+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.
+