Skip to content

Commit

Permalink
Use stdcall calling convention on 32-bit Windows
Browse files Browse the repository at this point in the history
Not all programming languages support the cdecl calling convention.
stdcall is what the Win32 API uses, and it seems to be the better choice
for maximum compatibility with other programming languages.

So, switch from cdecl to stdcall.

Resolves #58
  • Loading branch information
ebiggers committed Dec 27, 2019
1 parent faaad7b commit 5f38309
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 26 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,11 @@ This enables you to allocate an output buffer of the correct size without
guessing. However, libdeflate's decompression routines do optionally provide
the actual number of output bytes in case you need it.

Windows developers: note that the calling convention of libdeflate.dll is cdecl.
This differs from the Windows API, which uses stdcall. If you call into
libdeflate.dll using a non-C/C++ language, or dynamically using LoadLibrary(),
make sure to use the cdecl calling convention. Using the wrong calling
convention may crash your application.
Windows developers: note that the calling convention of libdeflate.dll is
"stdcall" -- the same as the Win32 API. If you call into libdeflate.dll using a
non-C/C++ language, or dynamically using LoadLibrary(), make sure to use the
stdcall convention. Using the wrong convention may crash your application.
(Note: older versions of libdeflate used the "cdecl" convention instead.)

# DEFLATE vs. zlib vs. gzip

Expand Down
14 changes: 10 additions & 4 deletions libdeflate.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ extern "C" {

/*
* On Windows, if you want to link to the DLL version of libdeflate, then
* #define LIBDEFLATE_DLL. Note that the calling convention is cdecl.
* #define LIBDEFLATE_DLL. Note that the calling convention is "stdcall".
*/
#ifdef LIBDEFLATE_DLL
# ifdef BUILDING_LIBDEFLATE
Expand All @@ -31,6 +31,12 @@ extern "C" {
# define LIBDEFLATEAPI_SYM_VISIBILITY
#endif

#if defined(_WIN32) && defined(__i386__)
# define LIBDEFLATEAPI_ABI __stdcall
#else
# define LIBDEFLATEAPI_ABI
#endif

#if defined(BUILDING_LIBDEFLATE) && defined(__GNUC__) && \
defined(_WIN32) && defined(__i386__)
/*
Expand All @@ -39,12 +45,12 @@ extern "C" {
* code when called from an MSVC-compiled application.
*/
# define LIBDEFLATEAPI_STACKALIGN __attribute__((force_align_arg_pointer))
#endif
#ifndef LIBDEFLATEAPI_STACKALIGN
#else
# define LIBDEFLATEAPI_STACKALIGN
#endif

#define LIBDEFLATEAPI LIBDEFLATEAPI_SYM_VISIBILITY LIBDEFLATEAPI_STACKALIGN
#define LIBDEFLATEAPI LIBDEFLATEAPI_SYM_VISIBILITY LIBDEFLATEAPI_ABI \
LIBDEFLATEAPI_STACKALIGN

/* ========================================================================== */
/* Compression */
Expand Down
28 changes: 20 additions & 8 deletions programs/checksum.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,32 @@ show_usage(FILE *fp)
program_invocation_name);
}

typedef u32 (*cksum_fn_t)(u32, const void *, size_t);

static u32
adler32_libdeflate(u32 adler, const void *buf, size_t len)
{
return libdeflate_adler32(adler, buf, len);
}

static u32
zlib_adler32(u32 adler, const void *buf, size_t len)
crc32_libdeflate(u32 crc, const void *buf, size_t len)
{
return libdeflate_crc32(crc, buf, len);
}

static u32
adler32_zlib(u32 adler, const void *buf, size_t len)
{
return adler32(adler, buf, len);
}

static u32
zlib_crc32(u32 crc, const void *buf, size_t len)
crc32_zlib(u32 crc, const void *buf, size_t len)
{
return crc32(crc, buf, len);
}

typedef u32 (*cksum_fn_t)(u32, const void *, size_t);

static int
checksum_stream(struct file_stream *in, cksum_fn_t cksum, u32 *sum,
void *buf, size_t bufsize, u64 *size_ret, u64 *elapsed_ret)
Expand Down Expand Up @@ -137,14 +149,14 @@ tmain(int argc, tchar *argv[])

if (use_adler32) {
if (use_zlib_impl)
cksum = zlib_adler32;
cksum = adler32_zlib;
else
cksum = libdeflate_adler32;
cksum = adler32_libdeflate;
} else {
if (use_zlib_impl)
cksum = zlib_crc32;
cksum = crc32_zlib;
else
cksum = libdeflate_crc32;
cksum = crc32_libdeflate;
}

buf = xmalloc(bufsize);
Expand Down
30 changes: 21 additions & 9 deletions programs/test_checksums.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,25 @@ static unsigned int rng_seed;
typedef u32 (*cksum_fn_t)(u32, const void *, size_t);

static u32
zlib_adler32(u32 adler, const void *buf, size_t len)
adler32_libdeflate(u32 adler, const void *buf, size_t len)
{
return libdeflate_adler32(adler, buf, len);
}

static u32
crc32_libdeflate(u32 crc, const void *buf, size_t len)
{
return libdeflate_crc32(crc, buf, len);
}

static u32
adler32_zlib(u32 adler, const void *buf, size_t len)
{
return adler32(adler, buf, len);
}

static u32
zlib_crc32(u32 crc, const void *buf, size_t len)
crc32_zlib(u32 crc, const void *buf, size_t len)
{
return crc32(crc, buf, len);
}
Expand Down Expand Up @@ -51,7 +63,7 @@ static void
test_initial_values(cksum_fn_t cksum, u32 expected)
{
ASSERT(cksum(0, NULL, 0) == expected);
if (cksum != zlib_adler32) /* broken */
if (cksum != adler32_zlib) /* broken */
ASSERT(cksum(0, NULL, 1) == expected);
ASSERT(cksum(0, NULL, 1234) == expected);
ASSERT(cksum(1234, NULL, 0) == expected);
Expand Down Expand Up @@ -100,14 +112,14 @@ static void
test_crc32(const void *buffer, size_t size, u32 initial_value)
{
test_checksums(buffer, size, "CRC-32",
libdeflate_crc32, zlib_crc32, initial_value);
crc32_libdeflate, crc32_zlib, initial_value);
}

static void
test_adler32(const void *buffer, size_t size, u32 initial_value)
{
test_checksums(buffer, size, "Adler-32",
libdeflate_adler32, zlib_adler32, initial_value);
adler32_libdeflate, adler32_zlib, initial_value);
}

static void test_random_buffers(u8 *buffer, u8 *guarded_buf_end,
Expand Down Expand Up @@ -146,10 +158,10 @@ tmain(int argc, tchar *argv[])
rng_seed = time(NULL);
srand(rng_seed);

test_initial_values(libdeflate_adler32, 1);
test_initial_values(zlib_adler32, 1);
test_initial_values(libdeflate_crc32, 0);
test_initial_values(zlib_crc32, 0);
test_initial_values(adler32_libdeflate, 1);
test_initial_values(adler32_zlib, 1);
test_initial_values(crc32_libdeflate, 0);
test_initial_values(crc32_zlib, 0);

/* Test different buffer sizes and alignments */
test_random_buffers(buffer, guarded_buf_end, 256, 5000);
Expand Down

0 comments on commit 5f38309

Please sign in to comment.