-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
issues with ABIs and struct return types #38258
Comments
Actually, this difference extends to 32bit as well. C++ methods have that slight difference in how they handle return types compared to C/C++ functions. A case where I encountered this issue was actually in binding COM interfaces. 99% of the time they'd just be returning Related issue rust-lang/rfcs#1342 |
Someone ran into this today https://users.rust-lang.org/t/returning-values-from-rust-to-c/11256 EDIT: actually reading more, maybe not... |
@steveklabnik (Turns out that was indeed this issue: the user added a constructor on the C++ side, making it non-POD, and didn't mention it originally.) |
In order to fully solve this we would need two things:
|
This is also an issue for Linux btw, see rust-lang/rust-bindgen#778. |
… Rust compiler supports it natively Instance methods like `ReturnType myMethod(T arg1, U arg2)` where ReturnType is non trivial are passed in MSVC as: rcx - this rdx - address of return value r8, r9 - arg1, arg2 But the extern "C" abi passes arguments to a function `ReturnType myFunction(ThisType* this, T arg1, U arg2)` as follows: rcx - address of return value rdx - this r8, r9 - arg1, arg2 The MSVC convention for x64 is similar to x86 thiscall. Thus, we can rewrite the methods returning non-trivial values to be functions returning void, passing the return value via the second argument (after the this pointer). This will enable them to be called correctly with the new signature using extern "C" abi. See <rust-lang/rust#38258>
The notion of "POD" here is idiosyncratic to the MSVC ABI (e.g. it does not match the C++ notion of "standard-layout"), so care should be taking with naming such a repr to not cause further confusion. |
With the MSVC x64 ABI, structs are returned in RAX if and only if they are <= 8 bytes in size, and are effectively a POD type. See https://msdn.microsoft.com/en-us/library/7572ztz4.aspx . Unfortunately, I can't figure out how to tell Rust this. In C++,
sk_sp<T>
has a user-defined constructor, destructor, etc. In Rust, I couldn't figure out any way to do this. It's defined as..This causes segfaults because the C++ calling convention isn't upheld. A temporary workaround is to just add another dummy field, making this type bigger than 8 bytes. This happens to work in this case since this type is only ever used as a smart pointer return type; params are passed as basic
T*
.Is there any way to tell
rustc
to treat this type as non-POD when giving it to LLVM? If not, can such a mechanism be added?The text was updated successfully, but these errors were encountered: