Skip to content

Extern blob is duplicated per platform #8509

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

Closed
klutzy opened this issue Aug 14, 2013 · 7 comments
Closed

Extern blob is duplicated per platform #8509

klutzy opened this issue Aug 14, 2013 · 7 comments

Comments

@klutzy
Copy link
Contributor

klutzy commented Aug 14, 2013

Usually C bindings requires different calling conventions per platform. For example, linux-32 usually uses cdecl, win-32 uses stdcall, and win-64 uses win64-specific convention.
So if we want to bind a function universally, we have to duplicate extern ... {} block for each platform, e.g.

#[cfg(target_os = "linux")]
extern "cdecl" {
    fn func();
    ...
}
#[cfg(target_os = "win32", target_arch = "x86")]
extern "stdcall" {
    fn func();
    ...
}
#[cfg(target_os = "win32", target_arch = "x86_64")]
extern { // this is identical to extern "C" or extern "cdecl"
    fn func();
    ...
}

which is inconvenient and fragile. (I actually copied large extern blob for Mingw-w64 support (#8488).)

Other option is to generate binding code per platform from template. lifthrasiir/rust-opengles-angle uses the approach for egl binding.

I think it's good to add default calling convention keyword e.g. "platform" so that

extern "platform" {
    fn func();
    ...
}

where "platform" is interpreted as cdecl for linux-32, stdcall for win32, and so on. It would solve the issue for most cases.

EDIT: in irc @luqmana suggested to change extern {} (no abi specified) as platform-native callconv. (It's currently interpreted as "cdecl".) I think it's the best option.

@luqmana
Copy link
Member

luqmana commented Aug 15, 2013

cc @nikomatsakis

@brson
Copy link
Contributor

brson commented Aug 15, 2013

I don't think it's generally true that a cdecl function on unix would be a stdcall function on win32. The win32 API specifically is stdcall, but the C api is still cdecl on windows. The win32/win64 split seems to be the place where this is a problem.

This specific case could be solved with a macro.

@brson
Copy link
Contributor

brson commented Aug 15, 2013

I wonder if MSVC uses the stdcall abi by default for normal user code.

@brson
Copy link
Contributor

brson commented Aug 15, 2013

Making "stdcall" just mean 'the x86_64 abi ' on 64-bit platforms (the same way "cdecl" does) would also solve this problem, though I don't think we should.

@nikomatsakis
Copy link
Contributor

In fact, the ABI strings were designed to accommodate this. They can handle "platform-specific" ABIs, and trans will select the most appropriate. The current rules may need some tweaking, I don't remember how stdcall fits in etc.

@nikomatsakis
Copy link
Contributor

Hmm, well, the ABI strings aren't quite able to handle this example because they only distinguish by architecture, not by O/S. But perhaps we should fix this. In that case, one could put extern "stdcall cdecl" and it would select stdcall on Windows. but I imagine the reason I didn't do this is that sometimes on linux code still uses the pascal calling convention. This could be accommodated by having another name for pascal calling convention on linux; I'm not sure what the standard names in use are though. Otherwise, I tend to agree with @brson; a macro might help here. (It's quite possible the current ABI sets should just go away in favor of such macros as well)

@klutzy
Copy link
Contributor Author

klutzy commented Nov 10, 2013

#10367 added extern "system". solved!

@klutzy klutzy closed this as completed Nov 10, 2013
flip1995 pushed a commit to flip1995/rust that referenced this issue Mar 24, 2022
Fix `unncessary_to_owned` false positive

Fix rust-lang#8507

changelog: none
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants