Repository navigation
Description
While testing variadic function support with raw-dylib I discovered that Rust requires such functions to use either "C" or "cdecl" ABIs but raw-dylib requires the "system" ABI on non-x86 Windows.
My undertstanding from discussing with @dpaoliello is that this is not an issue with raw-dylib itself but with Rust's insistence that such functions aren't allowed to use the "system" ABI. It's just that raw-dylib is very strict about calling convention so that's where the issue surfaced.
#[link(name = "library", modifiers = "+verbatim")]
extern "system" {
pub fn DbgPrint(format: *const u8, ...) -> u32;
}On x64 I should be able to compile this but Rust says no:
error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
--> src\lib.rs:3:5
|
3 | pub fn DbgPrint(format: *const u8, ...) -> u32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
This example works if I change the ABI to "cdecl" but that's not meant to be a valid ABI on x64 and so when I try to compile this with raw-dylib it fails:
#[link(name = "library", kind = "raw-dylib", modifiers = "+verbatim")]
extern "cdecl" {
pub fn DbgPrint(format: *const u8, ...) -> u32;
}error: ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture
--> src\lib.rs:3:5
|
3 | pub fn DbgPrint(format: *const u8, ...) -> u32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The practical result is that it is impossible to link this function with raw-dylib on non-x86.
Activity
compiler-errors commentedon Apr 19, 2023
cc #97971 which originally added variadics support to some other calling conventions (though not
extern "system"it seems) behind the feature gate#![feature(extended_varargs_abi_support)].kennykerr commentedon Apr 19, 2023
A workaround is to use "C" on non-x86 as I implemented here: microsoft/windows-rs#2458
dpaoliello commentedon Apr 19, 2023
@wesleywiser @nagisa Thoughts on permitting variadic parameters with the
systemcalling convention for non-x86 Windows? If #87678 gets merged then we'll be pushing folks to usesystemso that they get the correct calling convention for Windows APIs on all architectures, but that breaks compatibility with variadic parameters.RalfJung commentedon Jan 4, 2024
This work-around is causing pain. Would be great if there was a way that it could be avoided. :)
RalfJung commentedon Jan 4, 2024
There's a comment saying this can't work:
rust/compiler/rustc_target/src/spec/abi/mod.rs
Lines 70 to 78 in ef7ebaa
I don't understand anything about these ABIs so I can't say how accurate this is.
Also I see nothing here special-casing x86, so why does the issue specifically mention non-x86?
kennykerr commentedon Jan 4, 2024
Happy to update
windows-rsas soon as there's a way to avoid it. 😊beepster4096 commentedon Jan 4, 2024
Can we make
systemequal tocdeclwhen applied to a variadic function? It's supposed to be whatever ABI is correct for the system api andcdeclis the correct ABI for a variadic win32 function. According to the docs__stdcallacts as__cdeclwhen applied to a variadic function.beepster4096 commentedon Jan 4, 2024
Went ahead and opened #119587 for this.
Rollup merge of rust-lang#119587 - beepster4096:system_varargs, r=pet…
Unrolled build for rust-lang#119587
Rollup merge of rust-lang#142464 - RalfJung:variadic-fn-abi-error, r=…
Rollup merge of rust-lang#142464 - RalfJung:variadic-fn-abi-error, r=…
Unrolled build for #142464
Rollup merge of #142464 - RalfJung:variadic-fn-abi-error, r=workingju…
Rollup merge of #142464 - RalfJung:variadic-fn-abi-error, r=workingju…