Skip to content

Commit 6bb1683

Browse files
uint-natekennykerr
andauthored
Add --sys-fn-ptrs to generate function pointer types (#3782)
Co-authored-by: Kenny Kerr <[email protected]>
1 parent df79a4b commit 6bb1683

File tree

10 files changed

+531
-7
lines changed

10 files changed

+531
-7
lines changed

.github/workflows/clippy.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,8 @@ jobs:
302302
run: cargo clippy -p test_structs --tests
303303
- name: Check test_sys
304304
run: cargo clippy -p test_sys --tests
305+
- name: Check test_sys_fn_ptrs
306+
run: cargo clippy -p test_sys_fn_ptrs --tests
305307
- name: Check test_targets
306308
run: cargo clippy -p test_targets --tests
307309
- name: Check test_threading

.github/workflows/test.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,8 @@ jobs:
331331
run: cargo test -p test_structs --target ${{ matrix.target }}
332332
- name: Test test_sys
333333
run: cargo test -p test_sys --target ${{ matrix.target }}
334+
- name: Test test_sys_fn_ptrs
335+
run: cargo test -p test_sys_fn_ptrs --target ${{ matrix.target }}
334336
- name: Test test_targets
335337
run: cargo test -p test_targets --target ${{ matrix.target }}
336338
- name: Test test_threading
@@ -359,10 +361,10 @@ jobs:
359361
run: cargo test -p tool_bindgen --target ${{ matrix.target }}
360362
- name: Test tool_bindings
361363
run: cargo test -p tool_bindings --target ${{ matrix.target }}
362-
- name: Test tool_gnu
363-
run: cargo test -p tool_gnu --target ${{ matrix.target }}
364364
- name: Clean
365365
run: cargo clean
366+
- name: Test tool_gnu
367+
run: cargo test -p tool_gnu --target ${{ matrix.target }}
366368
- name: Test tool_license
367369
run: cargo test -p tool_license --target ${{ matrix.target }}
368370
- name: Test tool_merge

crates/libs/bindgen/src/config/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub struct Config<'a> {
2020
pub package: bool,
2121
pub rustfmt: &'a str,
2222
pub sys: bool,
23+
pub sys_fn_ptrs: bool,
2324
pub implement: bool,
2425
pub specific_deps: bool,
2526
pub derive: &'a Derive,

crates/libs/bindgen/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ use method_names::*;
8181
/// | `--no-comment` | Avoids generating the code generation comment. |
8282
/// | `--no-deps` | Avoids dependencies on the various `windows-*` crates. |
8383
/// | `--sys` | Generates raw or sys-style Rust bindings. |
84+
/// | `--sys-fn-ptrs` | Additionally generates function pointers for sys-style Rust bindings. |
8485
/// | `--implement` | Includes implementation traits for WinRT interfaces. |
8586
/// | `--link` | Overrides the default `windows-link` implementation for system calls. |
8687
///
@@ -278,6 +279,7 @@ where
278279
let mut rustfmt = String::new();
279280
let mut output = String::new();
280281
let mut sys = false;
282+
let mut sys_fn_ptrs = false;
281283
let mut link = String::new();
282284
let mut index = false;
283285

@@ -301,6 +303,7 @@ where
301303
"--no-toml" => no_toml = true,
302304
"--package" => package = true,
303305
"--sys" => sys = true,
306+
"--sys-fn-ptrs" => sys_fn_ptrs = true,
304307
"--implement" => implement = true,
305308
"--specific-deps" => specific_deps = true,
306309
"--link" => kind = ArgKind::Link,
@@ -435,6 +438,7 @@ where
435438
rustfmt: &rustfmt,
436439
output: &output,
437440
sys,
441+
sys_fn_ptrs,
438442
implement,
439443
specific_deps,
440444
link: &link,

crates/libs/bindgen/src/types/cpp_fn.rs

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,35 @@ impl CppFn {
2727
self.type_name().write(config, &[])
2828
}
2929

30+
pub fn write_fn_ptr(&self, config: &Config<'_>, underlying_types: bool) -> TokenStream {
31+
let ptr_name = self.method.name().to_string();
32+
let name = to_ident(&ptr_name);
33+
let abi = self.method.calling_convention();
34+
let signature = self.method.signature(self.namespace, &[]);
35+
36+
let params = signature.params.iter().map(|param| {
37+
let name = param.write_ident();
38+
let ty = if underlying_types {
39+
param.underlying_type().write_abi(config)
40+
} else {
41+
param.write_abi(config)
42+
};
43+
quote! { #name: #ty }
44+
});
45+
46+
let return_sig = config.write_return_sig(self.method, &signature, underlying_types);
47+
48+
let vararg = if config.sys && signature.call_flags.contains(MethodCallAttributes::VARARG) {
49+
quote! { , ... }
50+
} else {
51+
quote! {}
52+
};
53+
54+
quote! {
55+
pub type #name = unsafe extern #abi fn(#(#params),* #vararg) #return_sig;
56+
}
57+
}
58+
3059
pub fn write_link(&self, config: &Config, underlying_types: bool) -> TokenStream {
3160
let library = self.method.module_name();
3261
let symbol = self.method.import_name();
@@ -71,18 +100,30 @@ impl CppFn {
71100
let name = to_ident(self.method.name());
72101
let signature = self.method.signature(self.namespace, &[]);
73102

103+
let fn_ptr = self.write_fn_ptr(config, false);
74104
let link = self.write_link(config, false);
75105
let arches = write_arches(self.method);
76106
let cfg = self.write_cfg(config);
77107
let cfg = quote! { #arches #cfg };
78108
let window_long = self.write_window_long();
79109

80110
if config.sys {
81-
return quote! {
82-
#cfg
83-
#link
84-
#window_long
85-
};
111+
if config.sys_fn_ptrs {
112+
return quote! {
113+
#cfg
114+
#fn_ptr
115+
#window_long
116+
#cfg
117+
#link
118+
#window_long
119+
};
120+
} else {
121+
return quote! {
122+
#cfg
123+
#link
124+
#window_long
125+
};
126+
}
86127
}
87128

88129
let method = CppMethod::new(self.method, self.namespace);
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
[package]
2+
name = "test_sys_fn_ptrs"
3+
version = "0.0.0"
4+
edition = "2021"
5+
publish = false
6+
7+
[lib]
8+
doc = false
9+
doctest = false
10+
11+
[dependencies.windows-result]
12+
workspace = true
13+
14+
[dependencies.windows-strings]
15+
workspace = true
16+
17+
[dependencies.windows-link]
18+
workspace = true
19+
20+
[build-dependencies.windows-bindgen]
21+
workspace = true
22+
23+
[lints]
24+
workspace = true
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
fn main() {
2+
windows_bindgen::bindgen([
3+
"--out",
4+
"src/bindings.rs",
5+
"--filter",
6+
"WebAuthNAuthenticatorMakeCredential",
7+
"WebAuthNAuthenticatorGetAssertion",
8+
"LoadLibraryExA",
9+
"GetProcAddress",
10+
"FreeLibrary",
11+
"LOAD_LIBRARY_SEARCH_DEFAULT_DIRS",
12+
"--sys",
13+
"--sys-fn-ptrs",
14+
"--no-comment",
15+
"--no-deps",
16+
])
17+
.unwrap();
18+
}

0 commit comments

Comments
 (0)