Closed
Description
Functions using the stdcall
calling convention return values in one of three ways (wikipedia):
- 32 bits or smaller: in
EAX
register - 33-64 bits: in
EAX
andEDX
registers - 65 bits or larger: by a pointer passed into the function from the calling code
In the third case, the pointer is not considered to be part of the argument list size for the purposes of the @size
name mangling suffix. For example:
#include <stdint.h>
struct more_complex
{
int64_t a;
int64_t b;
int64_t c;
};
extern "C" __declspec(dllexport) more_complex __stdcall return_more_complex()
{
return { 123, 456, 789 };
}
D:\code\temp\link-rs>dumpbin /exports export.lib
Microsoft (R) COFF/PE Dumper Version 14.30.30528.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file export.lib
File Type: LIBRARY
Exports
ordinal name
_return_more_complex@0
However, if we try to link to this function from Rust:
#[derive(PartialEq)]
#[repr(C)]
struct more_complex {
a: i64,
b: i64,
c: i64,
}
#[link(name = "export")]
extern "system" {
fn return_more_complex() -> more_complex;
}
fn main() {
unsafe {
assert_eq!(return_more_complex(), more_complex { a: 123, b: 456, c: 789 });
println!("ok");
}
}
Then we get a linker error because the argument list size is incorrectly calculated as 4
instead of 0
:
D:\code\temp\link-rs>rustc import.rs --target i686-pc-windows-msvc
error: linking with `link.exe` failed: exit code: 1120
|
= note: import.import.25f85bb4-cgu.8.rcgu.o : error LNK2019: unresolved external symbol __imp__return_more_complex@4 referenced in function __ZN6import4main17h0ecc22ee2d1aa233E
import.exe : fatal error LNK1120: 1 unresolved externals
Thanks to @kennykerr for the repro!