diff --git a/.cargo/config.toml b/.cargo/config.toml index 189247dcf8..0973ccb656 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,4 +1,5 @@ [build] rustflags = [ # "--cfg", "windows_debugger_visualizer", + # "--cfg", "windows_raw_dylib", ] diff --git a/.github/workflows/raw_dylib.yml b/.github/workflows/raw_dylib.yml new file mode 100644 index 0000000000..d797028282 --- /dev/null +++ b/.github/workflows/raw_dylib.yml @@ -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 diff --git a/crates/libs/sys/Cargo.toml b/crates/libs/sys/Cargo.toml index 3f596f9aa2..0801580099 100644 --- a/crates/libs/sys/Cargo.toml +++ b/crates/libs/sys/Cargo.toml @@ -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] diff --git a/crates/libs/sys/src/core/mod.rs b/crates/libs/sys/src/core/mod.rs index 31a0f0ee0d..23c45e0764 100644 --- a/crates/libs/sys/src/core/mod.rs +++ b/crates/libs/sys/src/core/mod.rs @@ -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" { + 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) => ( diff --git a/crates/libs/sys/src/lib.rs b/crates/libs/sys/src/lib.rs index 238840ed51..ceae138fb7 100644 --- a/crates/libs/sys/src/lib.rs +++ b/crates/libs/sys/src/lib.rs @@ -5,6 +5,7 @@ Learn more about Rust for Windows here: 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; diff --git a/crates/libs/windows/src/core/delay_load.rs b/crates/libs/windows/src/core/delay_load.rs index 134aabbaa6..b223cbd1d2 100644 --- a/crates/libs/windows/src/core/delay_load.rs +++ b/crates/libs/windows/src/core/delay_load.rs @@ -1,4 +1,5 @@ use super::*; +use bindings::*; /// Attempts to load a function from a given library. /// @@ -23,10 +24,3 @@ pub unsafe fn delay_load(library: PCSTR, function: PCSTR) -> Option { 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; -} diff --git a/crates/libs/windows/src/core/mod.rs b/crates/libs/windows/src/core/mod.rs index bab2c2314e..eb8a45108d 100644 --- a/crates/libs/windows/src/core/mod.rs +++ b/crates/libs/windows/src/core/mod.rs @@ -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::*; @@ -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) => ( diff --git a/crates/libs/windows/src/lib.rs b/crates/libs/windows/src/lib.rs index ddf7b127df..03a9e976d7 100644 --- a/crates/libs/windows/src/lib.rs +++ b/crates/libs/windows/src/lib.rs @@ -5,6 +5,7 @@ Learn more about Rust for Windows here: