Add WinRT `noexcept` support (#3070)
This commit is contained in:
Родитель
7d94387a7c
Коммит
21d17ab998
|
@ -208,6 +208,8 @@ jobs:
|
|||
run: cargo clippy -p test_msrv
|
||||
- name: Clippy test_no_use
|
||||
run: cargo clippy -p test_no_use
|
||||
- name: Clippy test_noexcept
|
||||
run: cargo clippy -p test_noexcept
|
||||
- name: Clippy test_not_dll
|
||||
run: cargo clippy -p test_not_dll
|
||||
- name: Clippy test_query_signature
|
||||
|
|
|
@ -234,6 +234,8 @@ jobs:
|
|||
run: cargo test -p test_msrv --target ${{ matrix.target }} ${{ matrix.etc }}
|
||||
- name: Test test_no_use
|
||||
run: cargo test -p test_no_use --target ${{ matrix.target }} ${{ matrix.etc }}
|
||||
- name: Test test_noexcept
|
||||
run: cargo test -p test_noexcept --target ${{ matrix.target }} ${{ matrix.etc }}
|
||||
- name: Test test_not_dll
|
||||
run: cargo test -p test_not_dll --target ${{ matrix.target }} ${{ matrix.etc }}
|
||||
- name: Test test_query_signature
|
||||
|
@ -256,10 +258,10 @@ jobs:
|
|||
run: cargo test -p test_riddle --target ${{ matrix.target }} ${{ matrix.etc }}
|
||||
- name: Test test_standalone
|
||||
run: cargo test -p test_standalone --target ${{ matrix.target }} ${{ matrix.etc }}
|
||||
- name: Test test_string_param
|
||||
run: cargo test -p test_string_param --target ${{ matrix.target }} ${{ matrix.etc }}
|
||||
- name: Clean
|
||||
run: cargo clean
|
||||
- name: Test test_string_param
|
||||
run: cargo test -p test_string_param --target ${{ matrix.target }} ${{ matrix.etc }}
|
||||
- name: Test test_structs
|
||||
run: cargo test -p test_structs --target ${{ matrix.target }} ${{ matrix.etc }}
|
||||
- name: Test test_sys
|
||||
|
|
|
@ -475,6 +475,10 @@ fn method_def_last_error(row: MethodDef) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn method_def_is_noexcept(method: MethodDef) -> bool {
|
||||
method.has_attribute("NoExceptionAttribute")
|
||||
}
|
||||
|
||||
pub fn type_is_borrowed(ty: &Type) -> bool {
|
||||
match ty {
|
||||
Type::TypeDef(row, _) => !type_def_is_blittable(*row),
|
||||
|
|
|
@ -22,6 +22,7 @@ pub fn writer(
|
|||
let features = writer.cfg_features(&cfg);
|
||||
let args = gen_winrt_abi_args(writer, params);
|
||||
let params = gen_winrt_params(writer, params);
|
||||
let noexcept = metadata::method_def_is_noexcept(method);
|
||||
|
||||
let return_type_tokens = match &signature.return_type {
|
||||
metadata::Type::Void => quote! { () },
|
||||
|
@ -35,6 +36,18 @@ pub fn writer(
|
|||
}
|
||||
};
|
||||
|
||||
let return_type_tokens = if noexcept {
|
||||
if metadata::type_is_nullable(&signature.return_type) {
|
||||
quote! { -> Option<#return_type_tokens> }
|
||||
} else if signature.return_type == metadata::Type::Void {
|
||||
quote! {}
|
||||
} else {
|
||||
quote! { -> #return_type_tokens }
|
||||
}
|
||||
} else {
|
||||
quote! { -> windows_core::Result<#return_type_tokens> }
|
||||
};
|
||||
|
||||
let return_arg = match &signature.return_type {
|
||||
metadata::Type::Void => quote! {},
|
||||
_ => {
|
||||
|
@ -47,30 +60,60 @@ pub fn writer(
|
|||
}
|
||||
};
|
||||
|
||||
let vcall = quote! { (windows_core::Interface::vtable(this).#vname)(windows_core::Interface::as_raw(this), #args #return_arg) };
|
||||
|
||||
let vcall = match &signature.return_type {
|
||||
metadata::Type::Void => {
|
||||
quote! {
|
||||
(windows_core::Interface::vtable(this).#vname)(windows_core::Interface::as_raw(this), #args).ok()
|
||||
if noexcept {
|
||||
quote! {
|
||||
let hresult__ = #vcall;
|
||||
debug_assert!(hresult__.0 == 0);
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
#vcall.ok()
|
||||
}
|
||||
}
|
||||
}
|
||||
_ if signature.return_type.is_winrt_array() => {
|
||||
quote! {
|
||||
let mut result__ = core::mem::MaybeUninit::zeroed();
|
||||
(windows_core::Interface::vtable(this).#vname)(windows_core::Interface::as_raw(this), #args #return_arg)
|
||||
.map(|| result__.assume_init())
|
||||
if noexcept {
|
||||
quote! {
|
||||
let mut result__ = core::mem::MaybeUninit::zeroed();
|
||||
let hresult__ = #vcall;
|
||||
debug_assert!(hresult__.0 == 0);
|
||||
result__.assume_init()
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
let mut result__ = core::mem::MaybeUninit::zeroed();
|
||||
#vcall
|
||||
.map(|| result__.assume_init())
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let map = if metadata::type_is_blittable(&signature.return_type) {
|
||||
quote! { map(||result__) }
|
||||
} else {
|
||||
quote! { and_then(|| windows_core::Type::from_abi(result__)) }
|
||||
};
|
||||
|
||||
quote! {
|
||||
if noexcept {
|
||||
if metadata::type_is_blittable(&signature.return_type) {
|
||||
quote! {
|
||||
let mut result__ = core::mem::zeroed();
|
||||
let hresult__ = #vcall;
|
||||
debug_assert!(hresult__.0 == 0);
|
||||
result__ }
|
||||
} else {
|
||||
quote! {
|
||||
let mut result__ = core::mem::zeroed();
|
||||
let hresult__ = #vcall;
|
||||
debug_assert!(hresult__.0 == 0);
|
||||
core::mem::transmute(result__) }
|
||||
}
|
||||
} else if metadata::type_is_blittable(&signature.return_type) {
|
||||
quote! {
|
||||
let mut result__ = core::mem::zeroed();
|
||||
(windows_core::Interface::vtable(this).#vname)(windows_core::Interface::as_raw(this), #args #return_arg)
|
||||
.#map
|
||||
#vcall
|
||||
.map(||result__) }
|
||||
} else {
|
||||
quote! { let mut result__ = core::mem::zeroed();
|
||||
#vcall.and_then(|| windows_core::Type::from_abi(result__)) }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -78,7 +121,7 @@ pub fn writer(
|
|||
match kind {
|
||||
metadata::InterfaceKind::Default => quote! {
|
||||
#features
|
||||
pub fn #name<#generics>(&self, #params) -> windows_core::Result<#return_type_tokens> #where_clause {
|
||||
pub fn #name<#generics>(&self, #params) #return_type_tokens #where_clause {
|
||||
let this = self;
|
||||
unsafe {
|
||||
#vcall
|
||||
|
@ -90,7 +133,7 @@ pub fn writer(
|
|||
| metadata::InterfaceKind::Overridable => {
|
||||
quote! {
|
||||
#features
|
||||
pub fn #name<#generics>(&self, #params) -> windows_core::Result<#return_type_tokens> #where_clause {
|
||||
pub fn #name<#generics>(&self, #params) #return_type_tokens #where_clause {
|
||||
let this = &windows_core::Interface::cast::<#interface_name>(self)?;
|
||||
unsafe {
|
||||
#vcall
|
||||
|
@ -101,7 +144,7 @@ pub fn writer(
|
|||
metadata::InterfaceKind::Static => {
|
||||
quote! {
|
||||
#features
|
||||
pub fn #name<#generics>(#params) -> windows_core::Result<#return_type_tokens> #where_clause {
|
||||
pub fn #name<#generics>(#params) #return_type_tokens #where_clause {
|
||||
Self::#interface_name(|this| unsafe { #vcall })
|
||||
}
|
||||
}
|
||||
|
@ -189,10 +232,13 @@ pub fn gen_upcall(
|
|||
inner: TokenStream,
|
||||
this: bool,
|
||||
) -> TokenStream {
|
||||
let noexcept = metadata::method_def_is_noexcept(sig.def);
|
||||
|
||||
let invoke_args = sig
|
||||
.params
|
||||
.iter()
|
||||
.map(|param| gen_winrt_invoke_arg(writer, param));
|
||||
|
||||
let this = if this {
|
||||
quote! { this, }
|
||||
} else {
|
||||
|
@ -200,20 +246,39 @@ pub fn gen_upcall(
|
|||
};
|
||||
|
||||
match &sig.return_type {
|
||||
metadata::Type::Void => quote! {
|
||||
#inner(#this #(#invoke_args,)*).into()
|
||||
},
|
||||
metadata::Type::Void => {
|
||||
if noexcept {
|
||||
quote! {
|
||||
#inner(#this #(#invoke_args,)*);
|
||||
windows_core::HRESULT(0)
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
#inner(#this #(#invoke_args,)*).into()
|
||||
}
|
||||
}
|
||||
}
|
||||
_ if sig.return_type.is_winrt_array() => {
|
||||
quote! {
|
||||
match #inner(#this #(#invoke_args,)*) {
|
||||
Ok(ok__) => {
|
||||
let (ok_data__, ok_data_len__) = ok__.into_abi();
|
||||
// use `core::ptr::write` since `result` could be uninitialized
|
||||
core::ptr::write(result__, ok_data__);
|
||||
core::ptr::write(result_size__, ok_data_len__);
|
||||
windows_core::HRESULT(0)
|
||||
if noexcept {
|
||||
quote! {
|
||||
let ok__ = #inner(#this #(#invoke_args,)*);
|
||||
let (ok_data__, ok_data_len__) = ok__.into_abi();
|
||||
core::ptr::write(result__, ok_data__);
|
||||
core::ptr::write(result_size__, ok_data_len__);
|
||||
windows_core::HRESULT(0)
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
match #inner(#this #(#invoke_args,)*) {
|
||||
Ok(ok__) => {
|
||||
let (ok_data__, ok_data_len__) = ok__.into_abi();
|
||||
// use `core::ptr::write` since `result` could be uninitialized
|
||||
core::ptr::write(result__, ok_data__);
|
||||
core::ptr::write(result_size__, ok_data_len__);
|
||||
windows_core::HRESULT(0)
|
||||
}
|
||||
Err(err) => err.into()
|
||||
}
|
||||
Err(err) => err.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -224,15 +289,25 @@ pub fn gen_upcall(
|
|||
quote! { core::mem::forget(ok__); }
|
||||
};
|
||||
|
||||
quote! {
|
||||
match #inner(#this #(#invoke_args,)*) {
|
||||
Ok(ok__) => {
|
||||
// use `core::ptr::write` since `result` could be uninitialized
|
||||
core::ptr::write(result__, core::mem::transmute_copy(&ok__));
|
||||
#forget
|
||||
windows_core::HRESULT(0)
|
||||
if noexcept {
|
||||
quote! {
|
||||
let ok__ = #inner(#this #(#invoke_args,)*);
|
||||
// use `core::ptr::write` since `result` could be uninitialized
|
||||
core::ptr::write(result__, core::mem::transmute_copy(&ok__));
|
||||
#forget
|
||||
windows_core::HRESULT(0)
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
match #inner(#this #(#invoke_args,)*) {
|
||||
Ok(ok__) => {
|
||||
// use `core::ptr::write` since `result` could be uninitialized
|
||||
core::ptr::write(result__, core::mem::transmute_copy(&ok__));
|
||||
#forget
|
||||
windows_core::HRESULT(0)
|
||||
}
|
||||
Err(err) => err.into()
|
||||
}
|
||||
Err(err) => err.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1284,31 +1284,44 @@ impl Writer {
|
|||
.contains(metadata::TypeAttributes::WindowsRuntime)
|
||||
{
|
||||
let is_delegate = def.kind() == metadata::TypeKind::Delegate;
|
||||
let noexcept = metadata::method_def_is_noexcept(signature.def);
|
||||
|
||||
let params = signature
|
||||
.params
|
||||
.iter()
|
||||
.map(|p| self.winrt_produce_type(p, !is_delegate));
|
||||
|
||||
let return_type = match &signature.return_type {
|
||||
metadata::Type::Void => quote! { () },
|
||||
_ => {
|
||||
let tokens = self.type_name(&signature.return_type);
|
||||
let return_type_tokens = if signature.return_type == metadata::Type::Void {
|
||||
quote! { () }
|
||||
} else {
|
||||
let tokens = self.type_name(&signature.return_type);
|
||||
|
||||
if signature.return_type.is_winrt_array() {
|
||||
quote! { windows_core::Array<#tokens> }
|
||||
} else {
|
||||
tokens
|
||||
}
|
||||
if signature.return_type.is_winrt_array() {
|
||||
quote! { windows_core::Array<#tokens> }
|
||||
} else {
|
||||
tokens
|
||||
}
|
||||
};
|
||||
|
||||
let return_type_tokens = if noexcept {
|
||||
if metadata::type_is_nullable(&signature.return_type) {
|
||||
quote! { -> Option<#return_type_tokens> }
|
||||
} else if signature.return_type == metadata::Type::Void {
|
||||
quote! {}
|
||||
} else {
|
||||
quote! { -> #return_type_tokens }
|
||||
}
|
||||
} else {
|
||||
quote! { -> windows_core::Result<#return_type_tokens> }
|
||||
};
|
||||
|
||||
let this = if is_delegate {
|
||||
quote! {}
|
||||
} else {
|
||||
quote! { &self, }
|
||||
};
|
||||
|
||||
quote! { (#this #(#params),*) -> windows_core::Result<#return_type> }
|
||||
quote! { (#this #(#params),*) #return_type_tokens }
|
||||
} else {
|
||||
let signature_kind = signature.kind();
|
||||
let mut params = quote! {};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
pub trait ICoreAutomationConnectionBoundObjectProvider_Impl: Sized {
|
||||
fn IsComThreadingRequired(&self) -> windows_core::Result<bool>;
|
||||
fn IsComThreadingRequired(&self) -> bool;
|
||||
}
|
||||
impl windows_core::RuntimeName for ICoreAutomationConnectionBoundObjectProvider {
|
||||
const NAME: &'static str = "Windows.UI.UIAutomation.Core.ICoreAutomationConnectionBoundObjectProvider";
|
||||
|
@ -9,13 +9,9 @@ impl ICoreAutomationConnectionBoundObjectProvider_Vtbl {
|
|||
unsafe extern "system" fn IsComThreadingRequired<Identity: windows_core::IUnknownImpl<Impl = Impl>, Impl: ICoreAutomationConnectionBoundObjectProvider_Impl, const OFFSET: isize>(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT {
|
||||
let this = (this as *const *const ()).offset(OFFSET) as *const Identity;
|
||||
let this = (*this).get_impl();
|
||||
match ICoreAutomationConnectionBoundObjectProvider_Impl::IsComThreadingRequired(this) {
|
||||
Ok(ok__) => {
|
||||
core::ptr::write(result__, core::mem::transmute_copy(&ok__));
|
||||
windows_core::HRESULT(0)
|
||||
}
|
||||
Err(err) => err.into(),
|
||||
}
|
||||
let ok__ = ICoreAutomationConnectionBoundObjectProvider_Impl::IsComThreadingRequired(this);
|
||||
core::ptr::write(result__, core::mem::transmute_copy(&ok__));
|
||||
windows_core::HRESULT(0)
|
||||
}
|
||||
Self {
|
||||
base__: windows_core::IInspectable_Vtbl::new::<Identity, ICoreAutomationConnectionBoundObjectProvider, OFFSET>(),
|
||||
|
|
|
@ -20,11 +20,13 @@ impl core::ops::Deref for ICoreAutomationConnectionBoundObjectProvider {
|
|||
}
|
||||
windows_core::imp::interface_hierarchy!(ICoreAutomationConnectionBoundObjectProvider, windows_core::IUnknown, windows_core::IInspectable);
|
||||
impl ICoreAutomationConnectionBoundObjectProvider {
|
||||
pub fn IsComThreadingRequired(&self) -> windows_core::Result<bool> {
|
||||
pub fn IsComThreadingRequired(&self) -> bool {
|
||||
let this = self;
|
||||
unsafe {
|
||||
let mut result__ = core::mem::zeroed();
|
||||
(windows_core::Interface::vtable(this).IsComThreadingRequired)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__)
|
||||
let hresult__ = (windows_core::Interface::vtable(this).IsComThreadingRequired)(windows_core::Interface::as_raw(this), &mut result__);
|
||||
debug_assert!(hresult__.0 == 0);
|
||||
result__
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,11 +44,13 @@ pub struct IAutomationTextRange_Vtbl {
|
|||
pub struct AutomationConnection(windows_core::IUnknown);
|
||||
windows_core::imp::interface_hierarchy!(AutomationConnection, windows_core::IUnknown, windows_core::IInspectable);
|
||||
impl AutomationConnection {
|
||||
pub fn IsRemoteSystem(&self) -> windows_core::Result<bool> {
|
||||
pub fn IsRemoteSystem(&self) -> bool {
|
||||
let this = self;
|
||||
unsafe {
|
||||
let mut result__ = core::mem::zeroed();
|
||||
(windows_core::Interface::vtable(this).IsRemoteSystem)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__)
|
||||
let hresult__ = (windows_core::Interface::vtable(this).IsRemoteSystem)(windows_core::Interface::as_raw(this), &mut result__);
|
||||
debug_assert!(hresult__.0 == 0);
|
||||
result__
|
||||
}
|
||||
}
|
||||
pub fn AppUserModelId(&self) -> windows_core::Result<windows_core::HSTRING> {
|
||||
|
@ -108,11 +110,13 @@ unsafe impl Sync for AutomationConnectionBoundObject {}
|
|||
pub struct AutomationElement(windows_core::IUnknown);
|
||||
windows_core::imp::interface_hierarchy!(AutomationElement, windows_core::IUnknown, windows_core::IInspectable);
|
||||
impl AutomationElement {
|
||||
pub fn IsRemoteSystem(&self) -> windows_core::Result<bool> {
|
||||
pub fn IsRemoteSystem(&self) -> bool {
|
||||
let this = self;
|
||||
unsafe {
|
||||
let mut result__ = core::mem::zeroed();
|
||||
(windows_core::Interface::vtable(this).IsRemoteSystem)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__)
|
||||
let hresult__ = (windows_core::Interface::vtable(this).IsRemoteSystem)(windows_core::Interface::as_raw(this), &mut result__);
|
||||
debug_assert!(hresult__.0 == 0);
|
||||
result__
|
||||
}
|
||||
}
|
||||
pub fn AppUserModelId(&self) -> windows_core::Result<windows_core::HSTRING> {
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
[package]
|
||||
name = "test_noexcept"
|
||||
version = "0.0.0"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
[dependencies.windows-core]
|
||||
path = "../../libs/core"
|
||||
|
||||
[build-dependencies.windows-bindgen]
|
||||
path = "../../libs/bindgen"
|
||||
|
||||
[build-dependencies]
|
||||
cc = "1.0"
|
||||
|
||||
[build-dependencies.cppwinrt]
|
||||
path = "../../libs/cppwinrt"
|
|
@ -0,0 +1,59 @@
|
|||
fn main() {
|
||||
if !cfg!(target_env = "msvc") {
|
||||
return;
|
||||
}
|
||||
|
||||
println!("cargo:rerun-if-changed=src/test.idl");
|
||||
let metadata_dir = format!("{}\\System32\\WinMetadata", env!("windir"));
|
||||
let mut command = std::process::Command::new("midlrt.exe");
|
||||
println!("cargo:rerun-if-changed=src/interop.cpp");
|
||||
println!("cargo:rustc-link-lib=windows.0.52.0");
|
||||
|
||||
command.args([
|
||||
"/winrt",
|
||||
"/nomidl",
|
||||
"/h",
|
||||
"nul",
|
||||
"/metadata_dir",
|
||||
&metadata_dir,
|
||||
"/reference",
|
||||
&format!("{metadata_dir}\\Windows.Foundation.winmd"),
|
||||
"/winmd",
|
||||
"test.winmd",
|
||||
"src/test.idl",
|
||||
]);
|
||||
|
||||
if !command.status().unwrap().success() {
|
||||
panic!("Failed to run midlrt");
|
||||
}
|
||||
|
||||
if let Err(error) = windows_bindgen::bindgen([
|
||||
"--in",
|
||||
"test.winmd",
|
||||
&metadata_dir,
|
||||
"--out",
|
||||
"src/bindings.rs",
|
||||
"--filter",
|
||||
"Test",
|
||||
"--config",
|
||||
"implement",
|
||||
]) {
|
||||
panic!("{error}");
|
||||
}
|
||||
|
||||
cppwinrt::cppwinrt([
|
||||
"-in",
|
||||
"test.winmd",
|
||||
&format!("{}\\System32\\WinMetadata", env!("windir")),
|
||||
"-out",
|
||||
"src",
|
||||
])
|
||||
.unwrap();
|
||||
|
||||
cc::Build::new()
|
||||
.cpp(true)
|
||||
.std("c++20")
|
||||
.flag("/EHsc")
|
||||
.file("src/interop.cpp")
|
||||
.compile("interop");
|
||||
}
|
|
@ -0,0 +1,590 @@
|
|||
// Bindings generated by `windows-bindgen` 0.56.0
|
||||
|
||||
#![allow(
|
||||
non_snake_case,
|
||||
non_upper_case_globals,
|
||||
non_camel_case_types,
|
||||
dead_code,
|
||||
clippy::all
|
||||
)]
|
||||
windows_core::imp::define_interface!(ITest, ITest_Vtbl, 0x37b05fc1_6ee1_5798_b48d_602875fb73a2);
|
||||
impl core::ops::Deref for ITest {
|
||||
type Target = windows_core::IInspectable;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
unsafe { core::mem::transmute(self) }
|
||||
}
|
||||
}
|
||||
windows_core::imp::interface_hierarchy!(ITest, windows_core::IUnknown, windows_core::IInspectable);
|
||||
impl ITest {
|
||||
pub fn MethodString(&self, test: &windows_core::HSTRING) -> windows_core::Result<()> {
|
||||
let this = self;
|
||||
unsafe {
|
||||
(windows_core::Interface::vtable(this).MethodString)(
|
||||
windows_core::Interface::as_raw(this),
|
||||
core::mem::transmute_copy(test),
|
||||
)
|
||||
.ok()
|
||||
}
|
||||
}
|
||||
pub fn MethodInt32(&self, test: i32) -> windows_core::Result<()> {
|
||||
let this = self;
|
||||
unsafe {
|
||||
(windows_core::Interface::vtable(this).MethodInt32)(
|
||||
windows_core::Interface::as_raw(this),
|
||||
test,
|
||||
)
|
||||
.ok()
|
||||
}
|
||||
}
|
||||
pub fn MethodTest<P0>(&self, test: P0) -> windows_core::Result<()>
|
||||
where
|
||||
P0: windows_core::Param<ITest>,
|
||||
{
|
||||
let this = self;
|
||||
unsafe {
|
||||
(windows_core::Interface::vtable(this).MethodTest)(
|
||||
windows_core::Interface::as_raw(this),
|
||||
test.param().abi(),
|
||||
)
|
||||
.ok()
|
||||
}
|
||||
}
|
||||
pub fn String(&self) -> windows_core::Result<windows_core::HSTRING> {
|
||||
let this = self;
|
||||
unsafe {
|
||||
let mut result__ = core::mem::zeroed();
|
||||
(windows_core::Interface::vtable(this).String)(
|
||||
windows_core::Interface::as_raw(this),
|
||||
&mut result__,
|
||||
)
|
||||
.and_then(|| windows_core::Type::from_abi(result__))
|
||||
}
|
||||
}
|
||||
pub fn SetString(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> {
|
||||
let this = self;
|
||||
unsafe {
|
||||
(windows_core::Interface::vtable(this).SetString)(
|
||||
windows_core::Interface::as_raw(this),
|
||||
core::mem::transmute_copy(value),
|
||||
)
|
||||
.ok()
|
||||
}
|
||||
}
|
||||
pub fn Int32(&self) -> windows_core::Result<i32> {
|
||||
let this = self;
|
||||
unsafe {
|
||||
let mut result__ = core::mem::zeroed();
|
||||
(windows_core::Interface::vtable(this).Int32)(
|
||||
windows_core::Interface::as_raw(this),
|
||||
&mut result__,
|
||||
)
|
||||
.map(|| result__)
|
||||
}
|
||||
}
|
||||
pub fn SetInt32(&self, value: i32) -> windows_core::Result<()> {
|
||||
let this = self;
|
||||
unsafe {
|
||||
(windows_core::Interface::vtable(this).SetInt32)(
|
||||
windows_core::Interface::as_raw(this),
|
||||
value,
|
||||
)
|
||||
.ok()
|
||||
}
|
||||
}
|
||||
pub fn Test(&self) -> windows_core::Result<ITest> {
|
||||
let this = self;
|
||||
unsafe {
|
||||
let mut result__ = core::mem::zeroed();
|
||||
(windows_core::Interface::vtable(this).Test)(
|
||||
windows_core::Interface::as_raw(this),
|
||||
&mut result__,
|
||||
)
|
||||
.and_then(|| windows_core::Type::from_abi(result__))
|
||||
}
|
||||
}
|
||||
pub fn SetTest<P0>(&self, value: P0) -> windows_core::Result<()>
|
||||
where
|
||||
P0: windows_core::Param<ITest>,
|
||||
{
|
||||
let this = self;
|
||||
unsafe {
|
||||
(windows_core::Interface::vtable(this).SetTest)(
|
||||
windows_core::Interface::as_raw(this),
|
||||
value.param().abi(),
|
||||
)
|
||||
.ok()
|
||||
}
|
||||
}
|
||||
pub fn MethodStringN(&self, test: &windows_core::HSTRING) {
|
||||
let this = self;
|
||||
unsafe {
|
||||
let hresult__ = (windows_core::Interface::vtable(this).MethodStringN)(
|
||||
windows_core::Interface::as_raw(this),
|
||||
core::mem::transmute_copy(test),
|
||||
);
|
||||
debug_assert!(hresult__.0 == 0);
|
||||
}
|
||||
}
|
||||
pub fn MethodInt32N(&self, test: i32) {
|
||||
let this = self;
|
||||
unsafe {
|
||||
let hresult__ = (windows_core::Interface::vtable(this).MethodInt32N)(
|
||||
windows_core::Interface::as_raw(this),
|
||||
test,
|
||||
);
|
||||
debug_assert!(hresult__.0 == 0);
|
||||
}
|
||||
}
|
||||
pub fn MethodTestN<P0>(&self, test: P0)
|
||||
where
|
||||
P0: windows_core::Param<ITest>,
|
||||
{
|
||||
let this = self;
|
||||
unsafe {
|
||||
let hresult__ = (windows_core::Interface::vtable(this).MethodTestN)(
|
||||
windows_core::Interface::as_raw(this),
|
||||
test.param().abi(),
|
||||
);
|
||||
debug_assert!(hresult__.0 == 0);
|
||||
}
|
||||
}
|
||||
pub fn StringN(&self) -> windows_core::HSTRING {
|
||||
let this = self;
|
||||
unsafe {
|
||||
let mut result__ = core::mem::zeroed();
|
||||
let hresult__ = (windows_core::Interface::vtable(this).StringN)(
|
||||
windows_core::Interface::as_raw(this),
|
||||
&mut result__,
|
||||
);
|
||||
debug_assert!(hresult__.0 == 0);
|
||||
core::mem::transmute(result__)
|
||||
}
|
||||
}
|
||||
pub fn SetStringN(&self, value: &windows_core::HSTRING) {
|
||||
let this = self;
|
||||
unsafe {
|
||||
let hresult__ = (windows_core::Interface::vtable(this).SetStringN)(
|
||||
windows_core::Interface::as_raw(this),
|
||||
core::mem::transmute_copy(value),
|
||||
);
|
||||
debug_assert!(hresult__.0 == 0);
|
||||
}
|
||||
}
|
||||
pub fn Int32N(&self) -> i32 {
|
||||
let this = self;
|
||||
unsafe {
|
||||
let mut result__ = core::mem::zeroed();
|
||||
let hresult__ = (windows_core::Interface::vtable(this).Int32N)(
|
||||
windows_core::Interface::as_raw(this),
|
||||
&mut result__,
|
||||
);
|
||||
debug_assert!(hresult__.0 == 0);
|
||||
result__
|
||||
}
|
||||
}
|
||||
pub fn SetInt32N(&self, value: i32) {
|
||||
let this = self;
|
||||
unsafe {
|
||||
let hresult__ = (windows_core::Interface::vtable(this).SetInt32N)(
|
||||
windows_core::Interface::as_raw(this),
|
||||
value,
|
||||
);
|
||||
debug_assert!(hresult__.0 == 0);
|
||||
}
|
||||
}
|
||||
pub fn TestN(&self) -> Option<ITest> {
|
||||
let this = self;
|
||||
unsafe {
|
||||
let mut result__ = core::mem::zeroed();
|
||||
let hresult__ = (windows_core::Interface::vtable(this).TestN)(
|
||||
windows_core::Interface::as_raw(this),
|
||||
&mut result__,
|
||||
);
|
||||
debug_assert!(hresult__.0 == 0);
|
||||
core::mem::transmute(result__)
|
||||
}
|
||||
}
|
||||
pub fn SetTestN<P0>(&self, value: P0)
|
||||
where
|
||||
P0: windows_core::Param<ITest>,
|
||||
{
|
||||
let this = self;
|
||||
unsafe {
|
||||
let hresult__ = (windows_core::Interface::vtable(this).SetTestN)(
|
||||
windows_core::Interface::as_raw(this),
|
||||
value.param().abi(),
|
||||
);
|
||||
debug_assert!(hresult__.0 == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
impl windows_core::RuntimeType for ITest {
|
||||
const SIGNATURE: windows_core::imp::ConstBuffer =
|
||||
windows_core::imp::ConstBuffer::for_interface::<Self>();
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct ITest_Vtbl {
|
||||
pub base__: windows_core::IInspectable_Vtbl,
|
||||
pub MethodString: unsafe extern "system" fn(
|
||||
*mut core::ffi::c_void,
|
||||
core::mem::MaybeUninit<windows_core::HSTRING>,
|
||||
) -> windows_core::HRESULT,
|
||||
pub MethodInt32:
|
||||
unsafe extern "system" fn(*mut core::ffi::c_void, i32) -> windows_core::HRESULT,
|
||||
pub MethodTest: unsafe extern "system" fn(
|
||||
*mut core::ffi::c_void,
|
||||
*mut core::ffi::c_void,
|
||||
) -> windows_core::HRESULT,
|
||||
pub String: unsafe extern "system" fn(
|
||||
*mut core::ffi::c_void,
|
||||
*mut core::mem::MaybeUninit<windows_core::HSTRING>,
|
||||
) -> windows_core::HRESULT,
|
||||
pub SetString: unsafe extern "system" fn(
|
||||
*mut core::ffi::c_void,
|
||||
core::mem::MaybeUninit<windows_core::HSTRING>,
|
||||
) -> windows_core::HRESULT,
|
||||
pub Int32: unsafe extern "system" fn(*mut core::ffi::c_void, *mut i32) -> windows_core::HRESULT,
|
||||
pub SetInt32: unsafe extern "system" fn(*mut core::ffi::c_void, i32) -> windows_core::HRESULT,
|
||||
pub Test: unsafe extern "system" fn(
|
||||
*mut core::ffi::c_void,
|
||||
*mut *mut core::ffi::c_void,
|
||||
) -> windows_core::HRESULT,
|
||||
pub SetTest: unsafe extern "system" fn(
|
||||
*mut core::ffi::c_void,
|
||||
*mut core::ffi::c_void,
|
||||
) -> windows_core::HRESULT,
|
||||
pub MethodStringN: unsafe extern "system" fn(
|
||||
*mut core::ffi::c_void,
|
||||
core::mem::MaybeUninit<windows_core::HSTRING>,
|
||||
) -> windows_core::HRESULT,
|
||||
pub MethodInt32N:
|
||||
unsafe extern "system" fn(*mut core::ffi::c_void, i32) -> windows_core::HRESULT,
|
||||
pub MethodTestN: unsafe extern "system" fn(
|
||||
*mut core::ffi::c_void,
|
||||
*mut core::ffi::c_void,
|
||||
) -> windows_core::HRESULT,
|
||||
pub StringN: unsafe extern "system" fn(
|
||||
*mut core::ffi::c_void,
|
||||
*mut core::mem::MaybeUninit<windows_core::HSTRING>,
|
||||
) -> windows_core::HRESULT,
|
||||
pub SetStringN: unsafe extern "system" fn(
|
||||
*mut core::ffi::c_void,
|
||||
core::mem::MaybeUninit<windows_core::HSTRING>,
|
||||
) -> windows_core::HRESULT,
|
||||
pub Int32N:
|
||||
unsafe extern "system" fn(*mut core::ffi::c_void, *mut i32) -> windows_core::HRESULT,
|
||||
pub SetInt32N: unsafe extern "system" fn(*mut core::ffi::c_void, i32) -> windows_core::HRESULT,
|
||||
pub TestN: unsafe extern "system" fn(
|
||||
*mut core::ffi::c_void,
|
||||
*mut *mut core::ffi::c_void,
|
||||
) -> windows_core::HRESULT,
|
||||
pub SetTestN: unsafe extern "system" fn(
|
||||
*mut core::ffi::c_void,
|
||||
*mut core::ffi::c_void,
|
||||
) -> windows_core::HRESULT,
|
||||
}
|
||||
pub trait ITest_Impl: Sized {
|
||||
fn MethodString(&self, test: &windows_core::HSTRING) -> windows_core::Result<()>;
|
||||
fn MethodInt32(&self, test: i32) -> windows_core::Result<()>;
|
||||
fn MethodTest(&self, test: Option<&ITest>) -> windows_core::Result<()>;
|
||||
fn String(&self) -> windows_core::Result<windows_core::HSTRING>;
|
||||
fn SetString(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>;
|
||||
fn Int32(&self) -> windows_core::Result<i32>;
|
||||
fn SetInt32(&self, value: i32) -> windows_core::Result<()>;
|
||||
fn Test(&self) -> windows_core::Result<ITest>;
|
||||
fn SetTest(&self, value: Option<&ITest>) -> windows_core::Result<()>;
|
||||
fn MethodStringN(&self, test: &windows_core::HSTRING);
|
||||
fn MethodInt32N(&self, test: i32);
|
||||
fn MethodTestN(&self, test: Option<&ITest>);
|
||||
fn StringN(&self) -> windows_core::HSTRING;
|
||||
fn SetStringN(&self, value: &windows_core::HSTRING);
|
||||
fn Int32N(&self) -> i32;
|
||||
fn SetInt32N(&self, value: i32);
|
||||
fn TestN(&self) -> Option<ITest>;
|
||||
fn SetTestN(&self, value: Option<&ITest>);
|
||||
}
|
||||
impl windows_core::RuntimeName for ITest {
|
||||
const NAME: &'static str = "Test.ITest";
|
||||
}
|
||||
impl ITest_Vtbl {
|
||||
pub const fn new<
|
||||
Identity: windows_core::IUnknownImpl<Impl = Impl>,
|
||||
Impl: ITest_Impl,
|
||||
const OFFSET: isize,
|
||||
>() -> ITest_Vtbl {
|
||||
unsafe extern "system" fn MethodString<
|
||||
Identity: windows_core::IUnknownImpl<Impl = Impl>,
|
||||
Impl: ITest_Impl,
|
||||
const OFFSET: isize,
|
||||
>(
|
||||
this: *mut core::ffi::c_void,
|
||||
test: core::mem::MaybeUninit<windows_core::HSTRING>,
|
||||
) -> windows_core::HRESULT {
|
||||
let this = (this as *const *const ()).offset(OFFSET) as *const Identity;
|
||||
let this = (*this).get_impl();
|
||||
ITest_Impl::MethodString(this, core::mem::transmute(&test)).into()
|
||||
}
|
||||
unsafe extern "system" fn MethodInt32<
|
||||
Identity: windows_core::IUnknownImpl<Impl = Impl>,
|
||||
Impl: ITest_Impl,
|
||||
const OFFSET: isize,
|
||||
>(
|
||||
this: *mut core::ffi::c_void,
|
||||
test: i32,
|
||||
) -> windows_core::HRESULT {
|
||||
let this = (this as *const *const ()).offset(OFFSET) as *const Identity;
|
||||
let this = (*this).get_impl();
|
||||
ITest_Impl::MethodInt32(this, test).into()
|
||||
}
|
||||
unsafe extern "system" fn MethodTest<
|
||||
Identity: windows_core::IUnknownImpl<Impl = Impl>,
|
||||
Impl: ITest_Impl,
|
||||
const OFFSET: isize,
|
||||
>(
|
||||
this: *mut core::ffi::c_void,
|
||||
test: *mut core::ffi::c_void,
|
||||
) -> windows_core::HRESULT {
|
||||
let this = (this as *const *const ()).offset(OFFSET) as *const Identity;
|
||||
let this = (*this).get_impl();
|
||||
ITest_Impl::MethodTest(this, windows_core::from_raw_borrowed(&test)).into()
|
||||
}
|
||||
unsafe extern "system" fn String<
|
||||
Identity: windows_core::IUnknownImpl<Impl = Impl>,
|
||||
Impl: ITest_Impl,
|
||||
const OFFSET: isize,
|
||||
>(
|
||||
this: *mut core::ffi::c_void,
|
||||
result__: *mut core::mem::MaybeUninit<windows_core::HSTRING>,
|
||||
) -> windows_core::HRESULT {
|
||||
let this = (this as *const *const ()).offset(OFFSET) as *const Identity;
|
||||
let this = (*this).get_impl();
|
||||
match ITest_Impl::String(this) {
|
||||
Ok(ok__) => {
|
||||
core::ptr::write(result__, core::mem::transmute_copy(&ok__));
|
||||
core::mem::forget(ok__);
|
||||
windows_core::HRESULT(0)
|
||||
}
|
||||
Err(err) => err.into(),
|
||||
}
|
||||
}
|
||||
unsafe extern "system" fn SetString<
|
||||
Identity: windows_core::IUnknownImpl<Impl = Impl>,
|
||||
Impl: ITest_Impl,
|
||||
const OFFSET: isize,
|
||||
>(
|
||||
this: *mut core::ffi::c_void,
|
||||
value: core::mem::MaybeUninit<windows_core::HSTRING>,
|
||||
) -> windows_core::HRESULT {
|
||||
let this = (this as *const *const ()).offset(OFFSET) as *const Identity;
|
||||
let this = (*this).get_impl();
|
||||
ITest_Impl::SetString(this, core::mem::transmute(&value)).into()
|
||||
}
|
||||
unsafe extern "system" fn Int32<
|
||||
Identity: windows_core::IUnknownImpl<Impl = Impl>,
|
||||
Impl: ITest_Impl,
|
||||
const OFFSET: isize,
|
||||
>(
|
||||
this: *mut core::ffi::c_void,
|
||||
result__: *mut i32,
|
||||
) -> windows_core::HRESULT {
|
||||
let this = (this as *const *const ()).offset(OFFSET) as *const Identity;
|
||||
let this = (*this).get_impl();
|
||||
match ITest_Impl::Int32(this) {
|
||||
Ok(ok__) => {
|
||||
core::ptr::write(result__, core::mem::transmute_copy(&ok__));
|
||||
windows_core::HRESULT(0)
|
||||
}
|
||||
Err(err) => err.into(),
|
||||
}
|
||||
}
|
||||
unsafe extern "system" fn SetInt32<
|
||||
Identity: windows_core::IUnknownImpl<Impl = Impl>,
|
||||
Impl: ITest_Impl,
|
||||
const OFFSET: isize,
|
||||
>(
|
||||
this: *mut core::ffi::c_void,
|
||||
value: i32,
|
||||
) -> windows_core::HRESULT {
|
||||
let this = (this as *const *const ()).offset(OFFSET) as *const Identity;
|
||||
let this = (*this).get_impl();
|
||||
ITest_Impl::SetInt32(this, value).into()
|
||||
}
|
||||
unsafe extern "system" fn Test<
|
||||
Identity: windows_core::IUnknownImpl<Impl = Impl>,
|
||||
Impl: ITest_Impl,
|
||||
const OFFSET: isize,
|
||||
>(
|
||||
this: *mut core::ffi::c_void,
|
||||
result__: *mut *mut core::ffi::c_void,
|
||||
) -> windows_core::HRESULT {
|
||||
let this = (this as *const *const ()).offset(OFFSET) as *const Identity;
|
||||
let this = (*this).get_impl();
|
||||
match ITest_Impl::Test(this) {
|
||||
Ok(ok__) => {
|
||||
core::ptr::write(result__, core::mem::transmute_copy(&ok__));
|
||||
core::mem::forget(ok__);
|
||||
windows_core::HRESULT(0)
|
||||
}
|
||||
Err(err) => err.into(),
|
||||
}
|
||||
}
|
||||
unsafe extern "system" fn SetTest<
|
||||
Identity: windows_core::IUnknownImpl<Impl = Impl>,
|
||||
Impl: ITest_Impl,
|
||||
const OFFSET: isize,
|
||||
>(
|
||||
this: *mut core::ffi::c_void,
|
||||
value: *mut core::ffi::c_void,
|
||||
) -> windows_core::HRESULT {
|
||||
let this = (this as *const *const ()).offset(OFFSET) as *const Identity;
|
||||
let this = (*this).get_impl();
|
||||
ITest_Impl::SetTest(this, windows_core::from_raw_borrowed(&value)).into()
|
||||
}
|
||||
unsafe extern "system" fn MethodStringN<
|
||||
Identity: windows_core::IUnknownImpl<Impl = Impl>,
|
||||
Impl: ITest_Impl,
|
||||
const OFFSET: isize,
|
||||
>(
|
||||
this: *mut core::ffi::c_void,
|
||||
test: core::mem::MaybeUninit<windows_core::HSTRING>,
|
||||
) -> windows_core::HRESULT {
|
||||
let this = (this as *const *const ()).offset(OFFSET) as *const Identity;
|
||||
let this = (*this).get_impl();
|
||||
ITest_Impl::MethodStringN(this, core::mem::transmute(&test));
|
||||
windows_core::HRESULT(0)
|
||||
}
|
||||
unsafe extern "system" fn MethodInt32N<
|
||||
Identity: windows_core::IUnknownImpl<Impl = Impl>,
|
||||
Impl: ITest_Impl,
|
||||
const OFFSET: isize,
|
||||
>(
|
||||
this: *mut core::ffi::c_void,
|
||||
test: i32,
|
||||
) -> windows_core::HRESULT {
|
||||
let this = (this as *const *const ()).offset(OFFSET) as *const Identity;
|
||||
let this = (*this).get_impl();
|
||||
ITest_Impl::MethodInt32N(this, test);
|
||||
windows_core::HRESULT(0)
|
||||
}
|
||||
unsafe extern "system" fn MethodTestN<
|
||||
Identity: windows_core::IUnknownImpl<Impl = Impl>,
|
||||
Impl: ITest_Impl,
|
||||
const OFFSET: isize,
|
||||
>(
|
||||
this: *mut core::ffi::c_void,
|
||||
test: *mut core::ffi::c_void,
|
||||
) -> windows_core::HRESULT {
|
||||
let this = (this as *const *const ()).offset(OFFSET) as *const Identity;
|
||||
let this = (*this).get_impl();
|
||||
ITest_Impl::MethodTestN(this, windows_core::from_raw_borrowed(&test));
|
||||
windows_core::HRESULT(0)
|
||||
}
|
||||
unsafe extern "system" fn StringN<
|
||||
Identity: windows_core::IUnknownImpl<Impl = Impl>,
|
||||
Impl: ITest_Impl,
|
||||
const OFFSET: isize,
|
||||
>(
|
||||
this: *mut core::ffi::c_void,
|
||||
result__: *mut core::mem::MaybeUninit<windows_core::HSTRING>,
|
||||
) -> windows_core::HRESULT {
|
||||
let this = (this as *const *const ()).offset(OFFSET) as *const Identity;
|
||||
let this = (*this).get_impl();
|
||||
let ok__ = ITest_Impl::StringN(this);
|
||||
core::ptr::write(result__, core::mem::transmute_copy(&ok__));
|
||||
core::mem::forget(ok__);
|
||||
windows_core::HRESULT(0)
|
||||
}
|
||||
unsafe extern "system" fn SetStringN<
|
||||
Identity: windows_core::IUnknownImpl<Impl = Impl>,
|
||||
Impl: ITest_Impl,
|
||||
const OFFSET: isize,
|
||||
>(
|
||||
this: *mut core::ffi::c_void,
|
||||
value: core::mem::MaybeUninit<windows_core::HSTRING>,
|
||||
) -> windows_core::HRESULT {
|
||||
let this = (this as *const *const ()).offset(OFFSET) as *const Identity;
|
||||
let this = (*this).get_impl();
|
||||
ITest_Impl::SetStringN(this, core::mem::transmute(&value));
|
||||
windows_core::HRESULT(0)
|
||||
}
|
||||
unsafe extern "system" fn Int32N<
|
||||
Identity: windows_core::IUnknownImpl<Impl = Impl>,
|
||||
Impl: ITest_Impl,
|
||||
const OFFSET: isize,
|
||||
>(
|
||||
this: *mut core::ffi::c_void,
|
||||
result__: *mut i32,
|
||||
) -> windows_core::HRESULT {
|
||||
let this = (this as *const *const ()).offset(OFFSET) as *const Identity;
|
||||
let this = (*this).get_impl();
|
||||
let ok__ = ITest_Impl::Int32N(this);
|
||||
core::ptr::write(result__, core::mem::transmute_copy(&ok__));
|
||||
windows_core::HRESULT(0)
|
||||
}
|
||||
unsafe extern "system" fn SetInt32N<
|
||||
Identity: windows_core::IUnknownImpl<Impl = Impl>,
|
||||
Impl: ITest_Impl,
|
||||
const OFFSET: isize,
|
||||
>(
|
||||
this: *mut core::ffi::c_void,
|
||||
value: i32,
|
||||
) -> windows_core::HRESULT {
|
||||
let this = (this as *const *const ()).offset(OFFSET) as *const Identity;
|
||||
let this = (*this).get_impl();
|
||||
ITest_Impl::SetInt32N(this, value);
|
||||
windows_core::HRESULT(0)
|
||||
}
|
||||
unsafe extern "system" fn TestN<
|
||||
Identity: windows_core::IUnknownImpl<Impl = Impl>,
|
||||
Impl: ITest_Impl,
|
||||
const OFFSET: isize,
|
||||
>(
|
||||
this: *mut core::ffi::c_void,
|
||||
result__: *mut *mut core::ffi::c_void,
|
||||
) -> windows_core::HRESULT {
|
||||
let this = (this as *const *const ()).offset(OFFSET) as *const Identity;
|
||||
let this = (*this).get_impl();
|
||||
let ok__ = ITest_Impl::TestN(this);
|
||||
core::ptr::write(result__, core::mem::transmute_copy(&ok__));
|
||||
core::mem::forget(ok__);
|
||||
windows_core::HRESULT(0)
|
||||
}
|
||||
unsafe extern "system" fn SetTestN<
|
||||
Identity: windows_core::IUnknownImpl<Impl = Impl>,
|
||||
Impl: ITest_Impl,
|
||||
const OFFSET: isize,
|
||||
>(
|
||||
this: *mut core::ffi::c_void,
|
||||
value: *mut core::ffi::c_void,
|
||||
) -> windows_core::HRESULT {
|
||||
let this = (this as *const *const ()).offset(OFFSET) as *const Identity;
|
||||
let this = (*this).get_impl();
|
||||
ITest_Impl::SetTestN(this, windows_core::from_raw_borrowed(&value));
|
||||
windows_core::HRESULT(0)
|
||||
}
|
||||
Self {
|
||||
base__: windows_core::IInspectable_Vtbl::new::<Identity, ITest, OFFSET>(),
|
||||
MethodString: MethodString::<Identity, Impl, OFFSET>,
|
||||
MethodInt32: MethodInt32::<Identity, Impl, OFFSET>,
|
||||
MethodTest: MethodTest::<Identity, Impl, OFFSET>,
|
||||
String: String::<Identity, Impl, OFFSET>,
|
||||
SetString: SetString::<Identity, Impl, OFFSET>,
|
||||
Int32: Int32::<Identity, Impl, OFFSET>,
|
||||
SetInt32: SetInt32::<Identity, Impl, OFFSET>,
|
||||
Test: Test::<Identity, Impl, OFFSET>,
|
||||
SetTest: SetTest::<Identity, Impl, OFFSET>,
|
||||
MethodStringN: MethodStringN::<Identity, Impl, OFFSET>,
|
||||
MethodInt32N: MethodInt32N::<Identity, Impl, OFFSET>,
|
||||
MethodTestN: MethodTestN::<Identity, Impl, OFFSET>,
|
||||
StringN: StringN::<Identity, Impl, OFFSET>,
|
||||
SetStringN: SetStringN::<Identity, Impl, OFFSET>,
|
||||
Int32N: Int32N::<Identity, Impl, OFFSET>,
|
||||
SetInt32N: SetInt32N::<Identity, Impl, OFFSET>,
|
||||
TestN: TestN::<Identity, Impl, OFFSET>,
|
||||
SetTestN: SetTestN::<Identity, Impl, OFFSET>,
|
||||
}
|
||||
}
|
||||
pub fn matches(iid: &windows_core::GUID) -> bool {
|
||||
iid == &<ITest as windows_core::Interface>::IID
|
||||
}
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
#include <windows.h>
|
||||
#include "winrt/Test.h"
|
||||
|
||||
using namespace winrt;
|
||||
using namespace winrt::Test;
|
||||
|
||||
void test_except(ITest const &test)
|
||||
{
|
||||
test.MethodString(L"abc");
|
||||
assert(test.String() == L"abc");
|
||||
|
||||
test.MethodInt32(123);
|
||||
assert(test.Int32() == 123);
|
||||
|
||||
test.MethodTest(test);
|
||||
assert(test.Test() == test);
|
||||
}
|
||||
|
||||
void test_noexcept(ITest const &test)
|
||||
{
|
||||
test.MethodStringN(L"abc");
|
||||
assert(test.StringN() == L"abc");
|
||||
|
||||
test.MethodInt32N(123);
|
||||
assert(test.Int32N() == 123);
|
||||
|
||||
test.MethodTestN(test);
|
||||
assert(test.TestN() == test);
|
||||
}
|
||||
|
||||
struct Implementation : implements<Implementation, ITest>
|
||||
{
|
||||
hstring m_string;
|
||||
int32_t m_int32;
|
||||
ITest m_test;
|
||||
|
||||
void MethodString(hstring const &value)
|
||||
{
|
||||
m_string = value;
|
||||
}
|
||||
void MethodInt32(int32_t value)
|
||||
{
|
||||
m_int32 = value;
|
||||
}
|
||||
void MethodTest(ITest const &value)
|
||||
{
|
||||
m_test = value;
|
||||
}
|
||||
hstring String() const
|
||||
{
|
||||
return m_string;
|
||||
}
|
||||
void String(hstring const &value)
|
||||
{
|
||||
m_string = value;
|
||||
}
|
||||
int32_t Int32() const
|
||||
{
|
||||
return m_int32;
|
||||
}
|
||||
void Int32(int32_t value)
|
||||
{
|
||||
m_int32 = value;
|
||||
}
|
||||
ITest Test() const
|
||||
{
|
||||
return m_test;
|
||||
}
|
||||
void Test(ITest const &value)
|
||||
{
|
||||
m_test = value;
|
||||
}
|
||||
|
||||
void MethodStringN(hstring const &value) noexcept
|
||||
{
|
||||
m_string = value;
|
||||
}
|
||||
void MethodInt32N(int32_t value) noexcept
|
||||
{
|
||||
m_int32 = value;
|
||||
}
|
||||
void MethodTestN(ITest const &value) noexcept
|
||||
{
|
||||
m_test = value;
|
||||
}
|
||||
hstring StringN() const noexcept
|
||||
{
|
||||
return m_string;
|
||||
}
|
||||
void StringN(hstring const &value) noexcept
|
||||
{
|
||||
m_string = value;
|
||||
}
|
||||
int32_t Int32N() const noexcept
|
||||
{
|
||||
return m_int32;
|
||||
}
|
||||
void Int32N(int32_t value) noexcept
|
||||
{
|
||||
m_int32 = value;
|
||||
}
|
||||
ITest TestN() const noexcept
|
||||
{
|
||||
return m_test;
|
||||
}
|
||||
void TestN(ITest const &value) noexcept
|
||||
{
|
||||
m_test = value;
|
||||
}
|
||||
};
|
||||
|
||||
extern "C"
|
||||
{
|
||||
HRESULT __stdcall consume(void *abi) noexcept
|
||||
try
|
||||
{
|
||||
ITest const &test = *reinterpret_cast<ITest const *>(&abi);
|
||||
|
||||
test_noexcept(test);
|
||||
test_except(test);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return to_hresult();
|
||||
}
|
||||
|
||||
HRESULT __stdcall produce(void **abi) noexcept
|
||||
try
|
||||
{
|
||||
*abi = detach_abi(make<Implementation>());
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return to_hresult();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
#![cfg(target_env = "msvc")]
|
||||
|
||||
mod bindings;
|
||||
pub use bindings::*;
|
||||
pub use windows_core::*;
|
||||
|
||||
pub fn consume(test: &ITest) -> Result<()> {
|
||||
extern "system" {
|
||||
fn consume(test: Ref<ITest>) -> HRESULT;
|
||||
}
|
||||
|
||||
unsafe { consume(std::mem::transmute_copy(test)).ok() }
|
||||
}
|
||||
|
||||
pub fn produce() -> Result<ITest> {
|
||||
extern "system" {
|
||||
fn produce(test: *mut *mut std::ffi::c_void) -> HRESULT;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let mut test = None;
|
||||
produce(&mut test as *mut _ as *mut _).ok()?;
|
||||
Type::from_default(&test)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
namespace Test
|
||||
{
|
||||
interface ITest
|
||||
{
|
||||
void MethodString(String test);
|
||||
void MethodInt32(Int32 test);
|
||||
void MethodTest(ITest test);
|
||||
String String;
|
||||
Int32 Int32;
|
||||
ITest Test;
|
||||
|
||||
[noexcept] void MethodStringN(String test);
|
||||
[noexcept] void MethodInt32N(Int32 test);
|
||||
[noexcept] void MethodTestN(ITest test);
|
||||
[noexcept] String StringN;
|
||||
[noexcept] Int32 Int32N;
|
||||
[noexcept] ITest TestN;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
#![cfg(target_env = "msvc")]
|
||||
|
||||
use test_noexcept::*;
|
||||
|
||||
#[implement(ITest)]
|
||||
#[derive(Default)]
|
||||
struct Test(std::sync::RwLock<(HSTRING, i32, Option<ITest>)>);
|
||||
|
||||
impl ITest_Impl for Test {
|
||||
fn MethodString(&self, test: &HSTRING) -> Result<()> {
|
||||
let mut this = self.0.write().unwrap();
|
||||
this.0 = test.clone();
|
||||
Ok(())
|
||||
}
|
||||
fn MethodInt32(&self, test: i32) -> Result<()> {
|
||||
let mut this = self.0.write().unwrap();
|
||||
this.1 = test;
|
||||
Ok(())
|
||||
}
|
||||
fn MethodTest(&self, test: Option<&ITest>) -> Result<()> {
|
||||
let mut this = self.0.write().unwrap();
|
||||
this.2 = test.cloned();
|
||||
Ok(())
|
||||
}
|
||||
fn String(&self) -> Result<HSTRING> {
|
||||
let this = self.0.read().unwrap();
|
||||
Ok(this.0.clone())
|
||||
}
|
||||
fn SetString(&self, value: &HSTRING) -> Result<()> {
|
||||
let mut this = self.0.write().unwrap();
|
||||
this.0 = value.clone();
|
||||
Ok(())
|
||||
}
|
||||
fn Int32(&self) -> Result<i32> {
|
||||
let this = self.0.read().unwrap();
|
||||
Ok(this.1)
|
||||
}
|
||||
fn SetInt32(&self, value: i32) -> Result<()> {
|
||||
let mut this = self.0.write().unwrap();
|
||||
this.1 = value;
|
||||
Ok(())
|
||||
}
|
||||
fn Test(&self) -> Result<ITest> {
|
||||
let this = self.0.read().unwrap();
|
||||
this.2.clone().ok_or_else(Error::empty)
|
||||
}
|
||||
fn SetTest(&self, value: Option<&ITest>) -> Result<()> {
|
||||
let mut this = self.0.write().unwrap();
|
||||
this.2 = value.cloned();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn MethodStringN(&self, test: &HSTRING) {
|
||||
let mut this = self.0.write().unwrap();
|
||||
this.0 = test.clone();
|
||||
}
|
||||
fn MethodInt32N(&self, test: i32) {
|
||||
let mut this = self.0.write().unwrap();
|
||||
this.1 = test;
|
||||
}
|
||||
fn MethodTestN(&self, test: Option<&ITest>) {
|
||||
let mut this = self.0.write().unwrap();
|
||||
this.2 = test.cloned();
|
||||
}
|
||||
fn StringN(&self) -> HSTRING {
|
||||
let this = self.0.read().unwrap();
|
||||
this.0.clone()
|
||||
}
|
||||
fn SetStringN(&self, value: &HSTRING) {
|
||||
let mut this = self.0.write().unwrap();
|
||||
this.0 = value.clone();
|
||||
}
|
||||
fn Int32N(&self) -> i32 {
|
||||
let this = self.0.read().unwrap();
|
||||
this.1
|
||||
}
|
||||
fn SetInt32N(&self, value: i32) {
|
||||
let mut this = self.0.write().unwrap();
|
||||
this.1 = value;
|
||||
}
|
||||
fn TestN(&self) -> Option<ITest> {
|
||||
let this = self.0.read().unwrap();
|
||||
this.2.clone()
|
||||
}
|
||||
fn SetTestN(&self, value: Option<&ITest>) {
|
||||
let mut this = self.0.write().unwrap();
|
||||
this.2 = value.cloned();
|
||||
}
|
||||
}
|
||||
|
||||
fn test_except(test: &ITest) -> Result<()> {
|
||||
test.MethodString(h!("abc"))?;
|
||||
assert_eq!(test.String()?, "abc");
|
||||
|
||||
test.MethodInt32(123)?;
|
||||
assert_eq!(test.Int32()?, 123);
|
||||
|
||||
test.MethodTest(test)?;
|
||||
assert_eq!(&test.Test()?, test);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn test_noexcept(test: &ITest) {
|
||||
test.MethodStringN(h!("abc"));
|
||||
assert_eq!(test.StringN(), "abc");
|
||||
|
||||
test.MethodInt32N(123);
|
||||
assert_eq!(test.Int32N(), 123);
|
||||
|
||||
test.MethodTestN(test);
|
||||
assert_eq!(test.TestN().as_ref(), Some(test));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rust() -> Result<()> {
|
||||
let test: ITest = Test::default().into();
|
||||
test_noexcept(&test);
|
||||
test_except(&test)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cpp() -> Result<()> {
|
||||
let test: ITest = Test::default().into();
|
||||
consume(&test)?;
|
||||
|
||||
let test: ITest = produce()?;
|
||||
test_noexcept(&test);
|
||||
test_except(&test)
|
||||
}
|
Загрузка…
Ссылка в новой задаче