Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[build]
rustflags = [
# "--cfg", "windows_debugger_visualizer",
# "--cfg", "windows_raw_dylib",
]
32 changes: 32 additions & 0 deletions .github/workflows/raw_dylib.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: raw_dylib

on:
pull_request:
push:
branches:
- master

env:
RUSTFLAGS: -Dwarnings --cfg windows_raw_dylib

jobs:
test:
name: Test
runs-on: windows-2019

strategy:
matrix:
include:
- target: x86_64-pc-windows-msvc
- target: i686-pc-windows-msvc
- target: x86_64-pc-windows-gnu
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Update toolchain
run: rustup update --no-self-update nightly && rustup default nightly-${{ matrix.target }}
- name: Add toolchain target
run: rustup target add ${{ matrix.target }}

- name: Test
run: cargo test -p test_calling_convention
2 changes: 1 addition & 1 deletion crates/libs/sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ default-target = "x86_64-pc-windows-msvc"
targets = []
all-features = true

[dependencies]
[target.'cfg(not(windows_raw_dylib))'.dependencies]
windows-targets = { path = "../targets", version = "0.43.0" }

[features]
Expand Down
23 changes: 23 additions & 0 deletions crates/libs/sys/src/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,29 @@ impl GUID {
}
}

#[cfg(all(windows_raw_dylib, target_arch = "x86"))]
#[macro_export]
macro_rules! link {
($library:literal $abi:literal $(#[$($doc:tt)*])* fn $name:ident($($arg:ident: $argty:ty),*)->$ret:ty) => (
#[link(name = $library, kind = "raw-dylib", modifiers = "+verbatim", import_name_type = "undecorated")]
extern $abi {
pub fn $name($($arg: $argty),*) -> $ret;
}
)
}

#[cfg(all(windows_raw_dylib, not(target_arch = "x86")))]
#[macro_export]
macro_rules! link {
($library:literal $abi:literal $(#[$($doc:tt)*])* fn $name:ident($($arg:ident: $argty:ty),*)->$ret:ty) => (
#[link(name = $library, kind = "raw-dylib", modifiers = "+verbatim")]
extern "system" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a specific reason this was made to ignore $abi? (it's now "C" rather than "system", as a workaround for variadic functions).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's a workaround for this: rust-lang/rust#110505

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's why it's C now, but why was it "system" rather than $abi?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the ABI is generally only relevant for x86 and "system" should work for all ARM64 and x64 Windows APIs.

pub fn $name($($arg: $argty),*) -> $ret;
}
)
}

#[cfg(not(windows_raw_dylib))]
#[macro_export]
macro_rules! link {
($library:literal $abi:literal $(#[$($doc:tt)*])* fn $name:ident($($arg:ident: $argty:ty),*)->$ret:ty) => (
Expand Down
1 change: 1 addition & 0 deletions crates/libs/sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Learn more about Rust for Windows here: <https://github.com/microsoft/windows-rs
#![no_std]
#![doc(html_no_source)]
#![allow(non_snake_case, clashing_extern_declarations)]
#![cfg_attr(windows_raw_dylib, feature(raw_dylib, native_link_modifiers_verbatim))]

extern crate self as windows_sys;
mod Windows;
Expand Down
4 changes: 3 additions & 1 deletion crates/libs/windows/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ rust-version = "1.64"
default-target = "x86_64-pc-windows-msvc"
targets = []

[dependencies]
[target.'cfg(not(windows_raw_dylib))'.dependencies]
windows-targets = { path = "../targets", version = "0.43.0" }

[dependencies]
windows-implement = { path = "../implement", version = "0.43.0", optional = true }
windows-interface = { path = "../interface", version = "0.43.0", optional = true }

Expand Down
27 changes: 15 additions & 12 deletions crates/libs/windows/src/core/bindings.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
use super::*;
use std::ffi::c_void;

link!("kernel32.dll""system" fn CloseHandle(handle: isize) -> i32);
link!("kernel32.dll" "system" fn GetLastError() -> u32);
link!("oleaut32.dll" "system" fn SysAllocStringLen(input: *const u16, len: u32) -> *const u16);
link!("oleaut32.dll" "system" fn SysFreeString(bstr: *const u16) -> ());
link!("oleaut32.dll" "system" fn SysStringLen(bstr: *const u16) -> u32);
link!("ole32.dll" "system" fn CoCreateGuid(guid: *mut GUID) -> HRESULT);
link!("ole32.dll" "system" fn CoTaskMemAlloc(len: usize) -> *mut c_void);
link!("ole32.dll" "system" fn CoTaskMemFree(ptr: *const c_void) -> ());
link!("oleaut32.dll" "system" fn GetErrorInfo(reserved: u32, info: *mut *mut c_void) -> HRESULT);
link!("oleaut32.dll" "system" fn SetErrorInfo(reserved: u32, info: *const c_void) -> HRESULT);
link!("kernel32.dll" "system" fn CreateEventW(attributes: *const c_void, manual_reset: i32, initial_state: i32, name: *const c_void) -> isize);
link!("kernel32.dll" "system" fn EncodePointer(ptr: *const c_void) -> *mut c_void);
link!("kernel32.dll" "system" fn FormatMessageW(flags: u32, source: *const c_void, code: u32, lang: u32, buffer: PWSTR, len: u32, args: *const *const i8) -> u32);
link!("kernel32.dll" "system" fn FreeLibrary(library: isize) -> i32);
link!("kernel32.dll" "system" fn GetLastError() -> u32);
link!("kernel32.dll" "system" fn GetProcAddress(library: isize, name: PCSTR) -> *const std::ffi::c_void);
link!("kernel32.dll" "system" fn GetProcessHeap() -> isize);
link!("kernel32.dll" "system" fn HeapAlloc(heap: isize, flags: u32, len: usize) -> *mut c_void);
link!("kernel32.dll" "system" fn HeapFree(heap: isize, flags: u32, ptr: *const c_void) -> i32);
link!("kernel32.dll" "system" fn CreateEventW(attributes: *const c_void, manual_reset: i32, initial_state: i32, name: *const c_void) -> isize);
link!("kernel32.dll" "system" fn WaitForSingleObject(handle: isize, milliseconds: u32) -> u32);
link!("kernel32.dll" "system" fn LoadLibraryA(name: PCSTR) -> isize);
link!("kernel32.dll" "system" fn SetEvent(handle: isize) -> i32);
link!("kernel32.dll" "system" fn WaitForSingleObject(handle: isize, milliseconds: u32) -> u32);
link!("kernel32.dll""system" fn CloseHandle(handle: isize) -> i32);
link!("ole32.dll" "system" fn CoCreateGuid(guid: *mut GUID) -> HRESULT);
link!("ole32.dll" "system" fn CoTaskMemAlloc(len: usize) -> *mut c_void);
link!("ole32.dll" "system" fn CoTaskMemFree(ptr: *const c_void) -> ());
link!("ole32.dll" "system" fn RoGetAgileReference(options: i32, iid: &GUID, object: *const c_void, reference: *mut *mut c_void) -> HRESULT);
link!("oleaut32.dll" "system" fn GetErrorInfo(reserved: u32, info: *mut *mut c_void) -> HRESULT);
link!("oleaut32.dll" "system" fn SetErrorInfo(reserved: u32, info: *const c_void) -> HRESULT);
link!("oleaut32.dll" "system" fn SysAllocStringLen(input: *const u16, len: u32) -> *const u16);
link!("oleaut32.dll" "system" fn SysFreeString(bstr: *const u16) -> ());
link!("oleaut32.dll" "system" fn SysStringLen(bstr: *const u16) -> u32);

pub const FORMAT_MESSAGE_ALLOCATE_BUFFER: u32 = 256;
pub const FORMAT_MESSAGE_FROM_SYSTEM: u32 = 4096;
Expand Down
8 changes: 1 addition & 7 deletions crates/libs/windows/src/core/delay_load.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::*;
use bindings::*;

/// Attempts to load a function from a given library.
///
Expand All @@ -23,10 +24,3 @@ pub unsafe fn delay_load<T>(library: PCSTR, function: PCSTR) -> Option<T> {
FreeLibrary(library);
None
}

#[link(name = "windows")]
extern "system" {
fn GetProcAddress(library: isize, name: PCSTR) -> *const std::ffi::c_void;
fn LoadLibraryA(name: PCSTR) -> isize;
fn FreeLibrary(library: isize) -> i32;
}
25 changes: 24 additions & 1 deletion crates/libs/windows/src/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub use array::*;
#[doc(hidden)]
pub use as_impl::*;
pub use borrowed::*;
pub(crate) use delay_load::*;
pub use delay_load::*;
pub use error::*;
pub use event::*;
pub use factory_cache::*;
Expand Down Expand Up @@ -125,6 +125,29 @@ macro_rules! interface_hierarchy {
#[doc(hidden)]
pub use interface_hierarchy;

#[cfg(all(windows_raw_dylib, target_arch = "x86"))]
#[macro_export]
macro_rules! link {
($library:literal $abi:literal fn $name:ident($($arg:ident: $argty:ty),*)->$ret:ty) => (
#[link(name = $library, kind = "raw-dylib", modifiers = "+verbatim", import_name_type = "undecorated")]
extern $abi {
pub fn $name($($arg: $argty),*) -> $ret;
}
)
}

#[cfg(all(windows_raw_dylib, not(target_arch = "x86")))]
#[macro_export]
macro_rules! link {
($library:literal $abi:literal fn $name:ident($($arg:ident: $argty:ty),*)->$ret:ty) => (
#[link(name = $library, kind = "raw-dylib", modifiers = "+verbatim")]
extern "system" {
pub fn $name($($arg: $argty),*) -> $ret;
}
)
}

#[cfg(not(windows_raw_dylib))]
#[macro_export]
macro_rules! link {
($library:literal $abi:literal fn $name:ident($($arg:ident: $argty:ty),*)->$ret:ty) => (
Expand Down
1 change: 1 addition & 0 deletions crates/libs/windows/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Learn more about Rust for Windows here: <https://github.com/microsoft/windows-rs
#![doc(html_no_source)]
#![allow(non_snake_case, clashing_extern_declarations)]
#![cfg_attr(windows_debugger_visualizer, feature(debugger_visualizer), debugger_visualizer(natvis_file = "../windows.natvis"))]
#![cfg_attr(windows_raw_dylib, feature(raw_dylib, native_link_modifiers_verbatim))]

extern crate self as windows;
mod Windows;
Expand Down
4 changes: 4 additions & 0 deletions crates/tests/calling_convention/tests/sys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@ fn calling_convention() {
GetTickCount();
}
}

#[test]
#[cfg(windows_raw_dylib)]
fn raw_dylib() {}
4 changes: 4 additions & 0 deletions crates/tests/calling_convention/tests/win.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@ fn calling_convention() {
GetTickCount();
}
}

#[test]
#[cfg(windows_raw_dylib)]
fn raw_dylib() {}
2 changes: 1 addition & 1 deletion crates/tools/sys/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ default-target = "x86_64-pc-windows-msvc"
targets = []
all-features = true

[dependencies]
[target.'cfg(not(windows_raw_dylib))'.dependencies]
windows-targets = { path = "../targets", version = "0.43.0" }

[features]
Expand Down
4 changes: 3 additions & 1 deletion crates/tools/windows/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,10 @@ rust-version = "1.64"
default-target = "x86_64-pc-windows-msvc"
targets = []

[dependencies]
[target.'cfg(not(windows_raw_dylib))'.dependencies]
windows-targets = { path = "../targets", version = "0.43.0" }

[dependencies]
windows-implement = { path = "../implement", version = "0.43.0", optional = true }
windows-interface = { path = "../interface", version = "0.43.0", optional = true }

Expand Down