{"action":"created","issue":{"url":"https://api.github.com/repos/rust-lang/rust/issues/27438","labels_url":"https://api.github.com/repos/rust-lang/rust/issues/27438/labels{/name}","comments_url":"https://api.github.com/repos/rust-lang/rust/issues/27438/comments","events_url":"https://api.github.com/repos/rust-lang/rust/issues/27438/events","html_url":"https://github.com/rust-lang/rust/issues/27438","id":98422921,"number":27438,"title":"Correctly handle dllimport on Windows/MSVC","user":{"login":"alexcrichton","id":64996,"avatar_url":"https://avatars.githubusercontent.com/u/64996?v=3","gravatar_id":"","url":"https://api.github.com/users/alexcrichton","html_url":"https://github.com/alexcrichton","followers_url":"https://api.github.com/users/alexcrichton/followers","following_url":"https://api.github.com/users/alexcrichton/following{/other_user}","gists_url":"https://api.github.com/users/alexcrichton/gists{/gist_id}","starred_url":"https://api.github.com/users/alexcrichton/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alexcrichton/subscriptions","organizations_url":"https://api.github.com/users/alexcrichton/orgs","repos_url":"https://api.github.com/users/alexcrichton/repos","events_url":"https://api.github.com/users/alexcrichton/events{/privacy}","received_events_url":"https://api.github.com/users/alexcrichton/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/rust-lang/rust/labels/A-windows","name":"A-windows","color":"d7e102"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-07-31T16:20:45Z","updated_at":"2015-08-12T07:53:06Z","closed_at":null,"body":"Currently the compiler makes basically no attempt to correctly use `dllimport`. As a bit of a refresher, the Windows linker requires that if you're importing symbols from a DLL that they're tagged with `dllimport`. This helps wire things up correctly at runtime and link-time. To help us out, though, the linker will patch up a few cases where `dllimport` is missing where it would otherwise be required. If a function in another DLL is linked to without `dllimport` then the linker will inject a local shim which adds a bit of indirection and runtime overhead but allows the crate to link correctly. For importing constants from other DLLs, however, the linker requires that `dllimport` is annotated correctly.\r\n\r\nIf we're targeting MSVC then the compiler currently puts `dllimport` on all imported constants from external crates, regardless of whether it's actually being imported from another crate. We rely on the linker fixing up all imports of functions. This ends up meaning that some crates don't link correctly, however (see this comment: https://github.com/rust-lang/rust/issues/26591#issuecomment-123513631).\r\n\r\nWe should fix the compiler's handling of dllimport in a few ways:\r\n\r\n* Functions should be tagged with `dllimport` where appropriate\r\n* FFI functions should also be tagged with `dllimport` where appropriate\r\n* Constants should not always be tagged with `dllimport` if they're not actually being imported from a DLL.\r\n\r\nI currently have a few thoughts running around in my head for fixing this, but nothing seems plausible enough to push on."},"comment":{"url":"https://api.github.com/repos/rust-lang/rust/issues/comments/130207374","html_url":"https://github.com/rust-lang/rust/issues/27438#issuecomment-130207374","issue_url":"https://api.github.com/repos/rust-lang/rust/issues/27438","id":130207374,"user":{"login":"vadimcn","id":3203809,"avatar_url":"https://avatars.githubusercontent.com/u/3203809?v=3","gravatar_id":"","url":"https://api.github.com/users/vadimcn","html_url":"https://github.com/vadimcn","followers_url":"https://api.github.com/users/vadimcn/followers","following_url":"https://api.github.com/users/vadimcn/following{/other_user}","gists_url":"https://api.github.com/users/vadimcn/gists{/gist_id}","starred_url":"https://api.github.com/users/vadimcn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vadimcn/subscriptions","organizations_url":"https://api.github.com/users/vadimcn/orgs","repos_url":"https://api.github.com/users/vadimcn/repos","events_url":"https://api.github.com/users/vadimcn/events{/privacy}","received_events_url":"https://api.github.com/users/vadimcn/received_events","type":"User","site_admin":false},"created_at":"2015-08-12T07:53:06Z","updated_at":"2015-08-12T07:53:06Z","body":"So basically, with MSVC toolchain you are supposed to know whether you are going to be linking with a static lib or a dll version of the upstream library when compiling your crate.\r\n\r\nHere's some ideas that come to my mind:\r\n- Add attributes for marking up linking modes of extern crates (e.g. `#[link_dll] extern crate foo`).   \r\nCons: since this wart is unique to MSVC toolchain, it is unlikely that crate authors, who are not on Windows, will pay any attention to it.  Besides, sometimes you simply can't tell in advance whether you'll need to link with a dll.\r\n- Don't mark anything as `dllimport`\r\n - Code refs: let the linker fix them  (extra jmp overhead in the case of dll library),\r\n - Data refs: avoid imported data altogether.   Many Windows libraries take this approach using getter/setter functions where having exported data cannot be avoided.    Cons: same as above.\r\n- Mark all imported symbols as `dllimport`:\r\n - Code refs: let the linker fix them (indirect call overhead for static libraries).\r\n - Data refs: emit extra `_imp__foo = &foo` symbols into static libraries (linking succeeds, but adds the overhead of indirect access).\r\n- Since rustc knows which flavor of the library it it going to link, it could take bitcode saved in Rust crates for LTO, add `dllimport` attribute to the symbols that need it, then re-emit the object file.   \r\nCons: increases compilation time, won't work for staticlibs (since those are not necessarily linked via rustc)\r\n"}}