From d7683d3098e2a965ff3a912aef3bd4b02b5a986a Mon Sep 17 00:00:00 2001 From: Tristan Labelle Date: Fri, 29 Mar 2024 15:59:08 -0400 Subject: [PATCH] IWeakReferenceSource support (#148) --- .../Resources/CWinRT/CppInteropWorkaround.h | 6 +- .../Support/CppInteropWorkaround.swift | 8 ++ .../Resources/Support/IInspectable.swift | 42 ++++--- .../Resources/Support/IWeakReference.swift | 82 ++++++++++++ .../Support/IWeakReferenceSource.swift | 71 +++++++++++ .../Resources/Support/WinRTWrapperBase.swift | 7 +- swiftwinrt/abi_writer.h | 3 + swiftwinrt/resources.rc | 2 + tests/test_app/WeakReferenceTests.swift | 33 +++++ tests/test_app/main.swift | 2 +- tests/test_app/test_app.exe.manifest | 6 +- .../Sources/CWinRT/include/Ctest_component.h | 3 + .../Sources/CWinRT/include/test_component.h | 117 ++++++++++++++++++ .../test_component/test_component+ABI.swift | 91 ++++++++++++++ .../test_component/test_component+Impl.swift | 29 +++++ .../test_component+MakeFromAbi.swift | 11 ++ .../test_component/test_component.swift | 53 ++++++++ tests/test_component/cpp/CMakeLists.txt | 1 + tests/test_component/cpp/WeakReferencer.cpp | 15 +++ tests/test_component/cpp/WeakReferencer.h | 22 ++++ tests/test_component/cpp/WeakReferencer.idl | 13 ++ tests/test_component/cpp/test_component.idl | 1 + 22 files changed, 592 insertions(+), 26 deletions(-) create mode 100644 swiftwinrt/Resources/Support/IWeakReference.swift create mode 100644 swiftwinrt/Resources/Support/IWeakReferenceSource.swift create mode 100644 tests/test_app/WeakReferenceTests.swift create mode 100644 tests/test_component/cpp/WeakReferencer.cpp create mode 100644 tests/test_component/cpp/WeakReferencer.h create mode 100644 tests/test_component/cpp/WeakReferencer.idl diff --git a/swiftwinrt/Resources/CWinRT/CppInteropWorkaround.h b/swiftwinrt/Resources/CWinRT/CppInteropWorkaround.h index 1d4c876c..31ca570c 100644 --- a/swiftwinrt/Resources/CWinRT/CppInteropWorkaround.h +++ b/swiftwinrt/Resources/CWinRT/CppInteropWorkaround.h @@ -98,6 +98,10 @@ struct StaticWCharArray_512 { #define IInspectableVtbl IInspectableVtbl_Workaround #define IMarshal IMarshal_Workaround #define IMarshalVtbl IMarshalVtbl_Workaround +#define IWeakReference IWeakReference_Workaround +#define IWeakReferenceVtbl IWeakReferenceVtbl_Workaround +#define IWeakReferenceSource IWeakReferenceSource_Workaround +#define IWeakReferenceSourceVtbl IWeakReferenceSourceVtbl_Workaround #define IActivationFactory IActivationFactory_Workaround #define IActivationFactoryVtbl IActivationFactoryVtbl_Workaround @@ -291,4 +295,4 @@ typedef struct IActivationFactoryVtbl interface IActivationFactory { CONST_VTBL struct IActivationFactoryVtbl *lpVtbl; -}; \ No newline at end of file +}; diff --git a/swiftwinrt/Resources/Support/CppInteropWorkaround.swift b/swiftwinrt/Resources/Support/CppInteropWorkaround.swift index 68d37bf9..7c68b013 100644 --- a/swiftwinrt/Resources/Support/CppInteropWorkaround.swift +++ b/swiftwinrt/Resources/Support/CppInteropWorkaround.swift @@ -12,6 +12,10 @@ public typealias C_IMarshal = C_BINDINGS_MODULE.IMarshal_Workaround public typealias C_IMarshalVtbl = C_BINDINGS_MODULE.IMarshalVtbl_Workaround public typealias C_IActivationFactory = C_BINDINGS_MODULE.IActivationFactory_Workaround public typealias C_IActivationFactoryVtbl = C_BINDINGS_MODULE.IActivationFactoryVtbl_Workaround +public typealias C_IWeakReference = C_BINDINGS_MODULE.IWeakReference_Workaround +public typealias C_IWeakReferenceVtbl = C_BINDINGS_MODULE.IWeakReferenceVtbl_Workaround +public typealias C_IWeakReferenceSource = C_BINDINGS_MODULE.IWeakReferenceSource_Workaround +public typealias C_IWeakReferenceSourceVtbl = C_BINDINGS_MODULE.IWeakReferenceSourceVtbl_Workaround internal let CoCreateInstance = C_BINDINGS_MODULE.CoCreateInstance_Workaround internal let UuidFromStringA = C_BINDINGS_MODULE.UuidFromStringA_Workaround internal let RoActivateInstance = C_BINDINGS_MODULE.RoActivateInstance_Workaround @@ -30,6 +34,10 @@ public typealias C_IMarshal = C_BINDINGS_MODULE.IMarshal public typealias C_IMarshalVtbl = C_BINDINGS_MODULE.IMarshalVtbl public typealias C_IActivationFactory = C_BINDINGS_MODULE.IActivationFactory public typealias C_IActivationFactoryVtbl = C_BINDINGS_MODULE.IActivationFactoryVtbl +public typealias C_IWeakReference = C_BINDINGS_MODULE.IWeakReference +public typealias C_IWeakReferenceVtbl = C_BINDINGS_MODULE.IWeakReferenceVtbl +public typealias C_IWeakReferenceSource = C_BINDINGS_MODULE.IWeakReferenceSource +public typealias C_IWeakReferenceSourceVtbl = C_BINDINGS_MODULE.IWeakReferenceSourceVtbl internal let CoCreateInstance = C_BINDINGS_MODULE.CoCreateInstance internal let UuidFromStringA = C_BINDINGS_MODULE.UuidFromStringA internal let RoActivateInstance = C_BINDINGS_MODULE.RoActivateInstance diff --git a/swiftwinrt/Resources/Support/IInspectable.swift b/swiftwinrt/Resources/Support/IInspectable.swift index 04fb211b..a08ceb53 100644 --- a/swiftwinrt/Resources/Support/IInspectable.swift +++ b/swiftwinrt/Resources/Support/IInspectable.swift @@ -79,28 +79,30 @@ public enum __ABI_ { public static func tryUnwrapFrom(raw pUnk: UnsafeMutableRawPointer?) -> AnyObject? { tryUnwrapFromBase(raw: pUnk) } + + internal static func queryInterface(_ pUnk: UnsafeMutablePointer?, _ riid: UnsafePointer?, _ ppvObject: UnsafeMutablePointer?) -> HRESULT { + guard let pUnk, let riid, let ppvObject else { return E_INVALIDARG } + ppvObject.pointee = nil + if riid.pointee == IUnknown.IID || + riid.pointee == IInspectable.IID || + riid.pointee == ISwiftImplemented.IID || + riid.pointee == IAgileObject.IID { + _ = pUnk.pointee.lpVtbl.pointee.AddRef(pUnk) + ppvObject.pointee = UnsafeMutableRawPointer(pUnk) + return S_OK + } + let swiftObj = AnyWrapper.tryUnwrapFrom(raw: pUnk) + if let customQueryInterface = swiftObj as? CustomQueryInterface, + let result = customQueryInterface.queryInterface(riid.pointee) { + ppvObject.pointee = result.detach() + return S_OK + } + return E_NOINTERFACE + } } internal static var IInspectableVTable: C_IInspectableVtbl = .init( - QueryInterface: { - guard let pUnk = $0, let riid = $1, let ppvObject = $2 else { return E_INVALIDARG } - ppvObject.pointee = nil - if riid.pointee == IUnknown.IID || - riid.pointee == IInspectable.IID || - riid.pointee == ISwiftImplemented.IID || - riid.pointee == IAgileObject.IID { - _ = pUnk.pointee.lpVtbl.pointee.AddRef(pUnk) - ppvObject.pointee = UnsafeMutableRawPointer(pUnk) - return S_OK - } - let swiftObj = AnyWrapper.tryUnwrapFrom(raw: pUnk) - if let customQueryInterface = swiftObj as? CustomQueryInterface, - let result = customQueryInterface.queryInterface(riid.pointee) { - ppvObject.pointee = result.detach() - return S_OK - } - return E_NOINTERFACE - }, + QueryInterface: { AnyWrapper.queryInterface($0, $1, $2) }, AddRef: { AnyWrapper.addRef($0) }, Release: { AnyWrapper.release($0) }, GetIids: { @@ -138,4 +140,4 @@ extension ComposableImpl where CABI == C_IInspectable { let vtblPtr = withUnsafeMutablePointer(to: &__ABI_.IInspectableVTable) { $0 } return .init(lpVtbl: vtblPtr) } -} \ No newline at end of file +} diff --git a/swiftwinrt/Resources/Support/IWeakReference.swift b/swiftwinrt/Resources/Support/IWeakReference.swift new file mode 100644 index 00000000..c600bc47 --- /dev/null +++ b/swiftwinrt/Resources/Support/IWeakReference.swift @@ -0,0 +1,82 @@ +import C_BINDINGS_MODULE + +internal let IID_IWeakReference: IID = IID(Data1: 0x00000037, Data2: 0x0000, Data3: 0x0000, Data4: (0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46)) // 00000037-0000-0000-C000-000000000046 + +fileprivate extension IUnknownRef { + func copyTo(_ riid: REFIID?, _ ppvObj: UnsafeMutablePointer?) -> HRESULT { + self.borrow.pointee.lpVtbl.pointee.QueryInterface(self.borrow, riid, ppvObj) + } +} + +func makeWeakReference(_ object: AnyObject, _ result: UnsafeMutablePointer) throws { + let wrapper = WeakReferenceWrapper(WeakReference(object)) + try wrapper.toABI { + _ = $0.pointee.lpVtbl.pointee.AddRef($0) + result.pointee = UnsafeMutableRawPointer($0) + } +} + +fileprivate class WeakReference { + public weak var target: AnyObject? + public init(_ target: AnyObject) { + self.target = target + } +} + +fileprivate class WeakReferenceWrapper: WinRTAbiBridgeWrapper { + init(_ weakReference: WeakReference){ + super.init(IWeakReferenceBridge.makeAbi(), weakReference) + } + + internal static func queryInterface(_ pUnk: UnsafeMutablePointer?, _ riid: UnsafePointer?, _ ppvObject: UnsafeMutablePointer?) -> HRESULT { + guard let pUnk, let riid, let ppvObject else { return E_INVALIDARG } + switch riid.pointee { + case IID_IWeakReference: + _ = pUnk.pointee.lpVtbl.pointee.AddRef(pUnk) + return S_OK + default: + guard let obj = WeakReferenceWrapper.tryUnwrapFromBase(raw: pUnk) else { return E_NOINTERFACE } + let anyWrapper = __ABI_.AnyWrapper(obj)! + return __ABI_.AnyWrapper.queryInterface(try! anyWrapper.toABI { $0 }, riid, ppvObject) + } + } +} + +fileprivate enum IWeakReferenceBridge: AbiBridge { + typealias CABI = C_IWeakReference + typealias SwiftProjection = WeakReference + + static func makeAbi() -> C_IWeakReference { + return C_IWeakReference(lpVtbl: &IWeakReferenceVTable) + } + + static func from(abi: ComPtr?) -> WeakReference? { + fatalError("Not needed") + } +} + +fileprivate var IWeakReferenceVTable: C_IWeakReferenceVtbl = .init( + QueryInterface: { WeakReferenceWrapper.queryInterface($0, $1, $2) }, + AddRef: { WeakReferenceWrapper.addRef($0) }, + Release: { WeakReferenceWrapper.release($0) }, + Resolve: { Resolve($0, $1, $2) } +) + +fileprivate func Resolve( + _ this: UnsafeMutablePointer?, + _ riid: UnsafePointer?, + _ ppvObject: UnsafeMutablePointer?>?) -> HRESULT { + guard let this, let riid, let ppvObject else { return E_INVALIDARG } + guard let weakReference = WeakReferenceWrapper.tryUnwrapFrom(abi: ComPtr(this)) else { return E_FAIL } + ppvObject.pointee = nil + // https://learn.microsoft.com/en-us/windows/win32/api/weakreference/nf-weakreference-iweakreference-resolve(refiid_iinspectable): + // "If you try to resolve a weak reference to a strong reference for an object that is no longer available, + // then IWeakReference::Resolve returns S_OK, but the objectReference parameter points to null. + guard let target = weakReference.target else { return S_OK } + + let anyWrapper = __ABI_.AnyWrapper(target)! + var rawObject: UnsafeMutableRawPointer? = nil + let result = __ABI_.AnyWrapper.queryInterface(try! anyWrapper.toABI { $0 }, riid, &rawObject) + ppvObject.pointee = rawObject?.bindMemory(to: C_IInspectable.self, capacity: 1) + return result +} diff --git a/swiftwinrt/Resources/Support/IWeakReferenceSource.swift b/swiftwinrt/Resources/Support/IWeakReferenceSource.swift new file mode 100644 index 00000000..5a118344 --- /dev/null +++ b/swiftwinrt/Resources/Support/IWeakReferenceSource.swift @@ -0,0 +1,71 @@ +import C_BINDINGS_MODULE + +internal let IID_IWeakReferenceSource: IID = IID(Data1: 0x00000038, Data2: 0x0000, Data3: 0x0000, Data4: (0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46)) // 00000038-0000-0000-C000-000000000046 + +fileprivate extension IUnknownRef { + func copyTo(_ riid: REFIID?, _ ppvObj: UnsafeMutablePointer?) -> HRESULT { + self.borrow.pointee.lpVtbl.pointee.QueryInterface(self.borrow, riid, ppvObj) + } +} + +func makeWeakReferenceSource(_ object: AnyObject, _ result: UnsafeMutablePointer) throws { + let wrapper = WeakReferenceSourceWrapper(object) + try wrapper.toABI { + _ = $0.pointee.lpVtbl.pointee.AddRef($0) + result.pointee = UnsafeMutableRawPointer($0) + } +} + +fileprivate class WeakReferenceSourceWrapper: WinRTAbiBridgeWrapper { + init(_ object: AnyObject){ + super.init(IWeakReferenceSourceBridge.makeAbi(), object) + } + + internal static func queryInterface(_ pUnk: UnsafeMutablePointer?, _ riid: UnsafePointer?, _ ppvObject: UnsafeMutablePointer?) -> HRESULT { + guard let pUnk, let riid, let ppvObject else { return E_INVALIDARG } + switch riid.pointee { + case IID_IWeakReferenceSource: + _ = pUnk.pointee.lpVtbl.pointee.AddRef(pUnk) + return S_OK + default: + guard let obj = WeakReferenceSourceWrapper.tryUnwrapFromBase(raw: pUnk) else { return E_NOINTERFACE } + let anyWrapper = __ABI_.AnyWrapper(obj)! + return __ABI_.AnyWrapper.queryInterface(try! anyWrapper.toABI { $0 }, riid, ppvObject) + } + } +} + +fileprivate enum IWeakReferenceSourceBridge: AbiBridge { + typealias CABI = C_IWeakReferenceSource + typealias SwiftProjection = AnyObject + + static func makeAbi() -> C_IWeakReferenceSource { + return C_IWeakReferenceSource(lpVtbl: &IWeakReferenceSourceVTable) + } + + static func from(abi: ComPtr?) -> AnyObject? { + fatalError("Not needed") + } +} + +fileprivate var IWeakReferenceSourceVTable: C_IWeakReferenceSourceVtbl = .init( + QueryInterface: { WeakReferenceSourceWrapper.queryInterface($0, $1, $2) }, + AddRef: { WeakReferenceSourceWrapper.addRef($0) }, + Release: { WeakReferenceSourceWrapper.release($0) }, + GetWeakReference: { GetWeakReference($0, $1) } +) + +fileprivate func GetWeakReference( + _ this: UnsafeMutablePointer?, + _ weakReference: UnsafeMutablePointer?>?) -> HRESULT { + guard let object = WeakReferenceSourceWrapper.tryUnwrapFrom(abi: ComPtr(this)) else { return E_FAIL } + guard let weakReference else { return E_INVALIDARG } + do { + var rawWeakReference: UnsafeMutableRawPointer? = nil + try makeWeakReference(object, &rawWeakReference) + weakReference.pointee = rawWeakReference?.bindMemory(to: C_IWeakReference.self, capacity: 1) + return S_OK + } catch { + return E_FAIL + } +} diff --git a/swiftwinrt/Resources/Support/WinRTWrapperBase.swift b/swiftwinrt/Resources/Support/WinRTWrapperBase.swift index 7bfcde29..325edaf0 100644 --- a/swiftwinrt/Resources/Support/WinRTWrapperBase.swift +++ b/swiftwinrt/Resources/Support/WinRTWrapperBase.swift @@ -155,11 +155,12 @@ open class WinRTWrapperBase { fileprivate static func queryInterfaceBase(_ pUnk: UnsafeMutablePointer, _ riid: UnsafePointer, _ result: UnsafeMutablePointer) -> HRESULT { guard let instance = tryUnwrapFromBase(raw: pUnk) else { return E_FAIL } - do - { + do { switch riid.pointee { case IID_IMarshal: try makeMarshaler(IUnknownRef(ComPtr(pUnk)), result) + case IID_IWeakReferenceSource: + try makeWeakReferenceSource(instance as AnyObject, result) default: guard let customQI = instance as? CustomQueryInterface, let iUnknownRef = customQI.queryInterface(riid.pointee) else { return E_NOINTERFACE } @@ -252,4 +253,4 @@ public class ReferenceWrapperBase: WinRTAbiBridgeWrapper public static func tryUnwrapFrom(raw pUnk: UnsafeMutableRawPointer?) -> I.SwiftProjection? { tryUnwrapFromBase(raw: pUnk) } -} \ No newline at end of file +} diff --git a/swiftwinrt/abi_writer.h b/swiftwinrt/abi_writer.h index 18423f12..35ddbb2a 100644 --- a/swiftwinrt/abi_writer.h +++ b/swiftwinrt/abi_writer.h @@ -291,6 +291,8 @@ namespace swiftwinrt w.c_mod = settings.get_c_module_name(); write_preamble(w, /* swift_code: */ false); w.write(R"(#pragma once +#define CINTERFACE + #include #include #include @@ -313,6 +315,7 @@ namespace swiftwinrt #pragma clang diagnostic ignored "-Wmicrosoft-enum-forward-reference" #include "CppInteropWorkaround.h" // TODO(WIN-860): Remove workaround once C++ interop issues with WinSDK.GUID are fixed. +#include #include "MemoryBuffer.h" // IMemoryBufferByteAccess (C definition) #include "robuffer.h" // IBufferByteAccess (C definition) )"); diff --git a/swiftwinrt/resources.rc b/swiftwinrt/resources.rc index b00b7c79..f14a369a 100644 --- a/swiftwinrt/resources.rc +++ b/swiftwinrt/resources.rc @@ -27,6 +27,8 @@ RawTyped RESOURCE_TYPE_SWIFT_SUPPORT_FILE "Resources\\Support\\RawTyped.swift" Runtime+Swift RESOURCE_TYPE_SWIFT_SUPPORT_FILE "Resources\\Support\\Runtime+Swift.swift" Swift+Extensions RESOURCE_TYPE_SWIFT_SUPPORT_FILE "Resources\\Support\\Swift+Extensions.swift" TrustLevel+Swift RESOURCE_TYPE_SWIFT_SUPPORT_FILE "Resources\\Support\\TrustLevel+Swift.swift" +IWeakReference RESOURCE_TYPE_SWIFT_SUPPORT_FILE "Resources\\Support\\IWeakReference.swift" +IWeakReferenceSource RESOURCE_TYPE_SWIFT_SUPPORT_FILE "Resources\\Support\\IWeakReferenceSource.swift" WinRTWrapperBase RESOURCE_TYPE_SWIFT_SUPPORT_FILE "Resources\\Support\\WinRTWrapperBase.swift" WinSDK+Extensions RESOURCE_TYPE_SWIFT_SUPPORT_FILE "Resources\\Support\\WinSDK+Extensions.swift" PropertyValue RESOURCE_TYPE_SWIFT_SUPPORT_FILE "Resources\\Support\\PropertyValue.swift" diff --git a/tests/test_app/WeakReferenceTests.swift b/tests/test_app/WeakReferenceTests.swift new file mode 100644 index 00000000..3d07fac8 --- /dev/null +++ b/tests/test_app/WeakReferenceTests.swift @@ -0,0 +1,33 @@ +import WinSDK +import XCTest +@_spi(WinRTInternal) import test_component +import Ctest_component +import Foundation + +class WeakReferenceTests : XCTestCase { + class Target: IReferenceTarget { + func method() {} + } + + public func testCreateAndResolve() throws { + let original = Target() + let weakReferencer = WeakReferencer(original) + let roundtrippedAny = try XCTUnwrap(weakReferencer.resolve()) + let roundtripped = try XCTUnwrap(roundtrippedAny as? Target) + XCTAssertIdentical(roundtripped, original) + } + + public func testNotStrong() throws { + var original: Target! = Target() + let weakReferencer = WeakReferencer(original) + original = nil + XCTAssertNil(try weakReferencer.resolve()) + } +} + +var weakReferenceTests: [XCTestCaseEntry] = [ + testCase([ + ("testCreateAndResolve", WeakReferenceTests.testCreateAndResolve), + ("testNotStrong", WeakReferenceTests.testNotStrong) + ]) +] diff --git a/tests/test_app/main.swift b/tests/test_app/main.swift index 2347a9a6..fb37caa7 100644 --- a/tests/test_app/main.swift +++ b/tests/test_app/main.swift @@ -460,7 +460,7 @@ var tests: [XCTestCaseEntry] = [ ("testUnicode", SwiftWinRTTests.testUnicode), ("testErrorInfo", SwiftWinRTTests.testErrorInfo), ]) -] + valueBoxingTests + eventTests + collectionTests + aggregationTests + asyncTests + memoryManagementTests + bufferTests +] + valueBoxingTests + eventTests + collectionTests + aggregationTests + asyncTests + memoryManagementTests + bufferTests + weakReferenceTests RoInitialize(RO_INIT_MULTITHREADED) XCTMain(tests) diff --git a/tests/test_app/test_app.exe.manifest b/tests/test_app/test_app.exe.manifest index a48b90b6..15728c89 100644 --- a/tests/test_app/test_app.exe.manifest +++ b/tests/test_app/test_app.exe.manifest @@ -66,5 +66,9 @@ name="test_component.BufferTester" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1" /> + - \ No newline at end of file + diff --git a/tests/test_component/Sources/CWinRT/include/Ctest_component.h b/tests/test_component/Sources/CWinRT/include/Ctest_component.h index 1faa06e1..74b8d1f8 100644 --- a/tests/test_component/Sources/CWinRT/include/Ctest_component.h +++ b/tests/test_component/Sources/CWinRT/include/Ctest_component.h @@ -1,6 +1,8 @@ // WARNING: Please don't edit this file. It was generated by Swift/WinRT v0.0.1 #pragma once +#define CINTERFACE + #include #include #include @@ -23,6 +25,7 @@ #pragma clang diagnostic ignored "-Wmicrosoft-enum-forward-reference" #include "CppInteropWorkaround.h" // TODO(WIN-860): Remove workaround once C++ interop issues with WinSDK.GUID are fixed. +#include #include "MemoryBuffer.h" // IMemoryBufferByteAccess (C definition) #include "robuffer.h" // IBufferByteAccess (C definition) #include "Windows.AI.MachineLearning.h" diff --git a/tests/test_component/Sources/CWinRT/include/test_component.h b/tests/test_component/Sources/CWinRT/include/test_component.h index c146159f..e670e5d8 100644 --- a/tests/test_component/Sources/CWinRT/include/test_component.h +++ b/tests/test_component/Sources/CWinRT/include/test_component.h @@ -198,6 +198,12 @@ typedef interface __x_ABI_Ctest__component_CIVoidToVoidDelegate __x_ABI_Ctest__c #endif // ____x_ABI_Ctest__component_CINullValuesStatics_FWD_DEFINED__ +#ifndef ____x_ABI_Ctest__component_CIReferenceTarget_FWD_DEFINED__ +#define ____x_ABI_Ctest__component_CIReferenceTarget_FWD_DEFINED__ + typedef interface __x_ABI_Ctest__component_CIReferenceTarget __x_ABI_Ctest__component_CIReferenceTarget; + +#endif // ____x_ABI_Ctest__component_CIReferenceTarget_FWD_DEFINED__ + #ifndef ____x_ABI_Ctest__component_CISimple_FWD_DEFINED__ #define ____x_ABI_Ctest__component_CISimple_FWD_DEFINED__ typedef interface __x_ABI_Ctest__component_CISimple __x_ABI_Ctest__component_CISimple; @@ -306,6 +312,18 @@ typedef interface __x_ABI_Ctest__component_CIVoidToVoidDelegate __x_ABI_Ctest__c #endif // ____x_ABI_Ctest__component_CIUnsealedDerivedOverrides_FWD_DEFINED__ +#ifndef ____x_ABI_Ctest__component_CIWeakReferencer_FWD_DEFINED__ +#define ____x_ABI_Ctest__component_CIWeakReferencer_FWD_DEFINED__ + typedef interface __x_ABI_Ctest__component_CIWeakReferencer __x_ABI_Ctest__component_CIWeakReferencer; + +#endif // ____x_ABI_Ctest__component_CIWeakReferencer_FWD_DEFINED__ + +#ifndef ____x_ABI_Ctest__component_CIWeakReferencerFactory_FWD_DEFINED__ +#define ____x_ABI_Ctest__component_CIWeakReferencerFactory_FWD_DEFINED__ + typedef interface __x_ABI_Ctest__component_CIWeakReferencerFactory __x_ABI_Ctest__component_CIWeakReferencerFactory; + +#endif // ____x_ABI_Ctest__component_CIWeakReferencerFactory_FWD_DEFINED__ + #ifndef ____x_ABI_Ctest__component_CInterfaceWithReturnDelegate_FWD_DEFINED__ #define ____x_ABI_Ctest__component_CInterfaceWithReturnDelegate_FWD_DEFINED__ typedef interface __x_ABI_Ctest__component_CInterfaceWithReturnDelegate __x_ABI_Ctest__component_CInterfaceWithReturnDelegate; @@ -3772,6 +3790,38 @@ struct __x_ABI_Ctest__component_CStructWithIReference EXTERN_C const IID IID___x_ABI_Ctest__component_CINullValuesStatics; #endif /* !defined(____x_ABI_Ctest__component_CINullValuesStatics_INTERFACE_DEFINED__) */ +#if !defined(____x_ABI_Ctest__component_CIReferenceTarget_INTERFACE_DEFINED__) + #define ____x_ABI_Ctest__component_CIReferenceTarget_INTERFACE_DEFINED__ + typedef struct __x_ABI_Ctest__component_CIReferenceTargetVtbl + { + BEGIN_INTERFACE + + HRESULT (STDMETHODCALLTYPE* QueryInterface)(__x_ABI_Ctest__component_CIReferenceTarget* This, + REFIID riid, + void** ppvObject); + ULONG (STDMETHODCALLTYPE* AddRef)(__x_ABI_Ctest__component_CIReferenceTarget* This); + ULONG (STDMETHODCALLTYPE* Release)(__x_ABI_Ctest__component_CIReferenceTarget* This); + HRESULT (STDMETHODCALLTYPE* GetIids)(__x_ABI_Ctest__component_CIReferenceTarget* This, + ULONG* iidCount, + IID** iids); + HRESULT (STDMETHODCALLTYPE* GetRuntimeClassName)(__x_ABI_Ctest__component_CIReferenceTarget* This, + HSTRING* className); + HRESULT (STDMETHODCALLTYPE* GetTrustLevel)(__x_ABI_Ctest__component_CIReferenceTarget* This, + TrustLevel* trustLevel); + HRESULT (STDMETHODCALLTYPE* Method)(__x_ABI_Ctest__component_CIReferenceTarget* This); + + END_INTERFACE + } __x_ABI_Ctest__component_CIReferenceTargetVtbl; + + interface __x_ABI_Ctest__component_CIReferenceTarget + { + CONST_VTBL struct __x_ABI_Ctest__component_CIReferenceTargetVtbl* lpVtbl; + }; + + + EXTERN_C const IID IID___x_ABI_Ctest__component_CIReferenceTarget; +#endif /* !defined(____x_ABI_Ctest__component_CIReferenceTarget_INTERFACE_DEFINED__) */ + #if !defined(____x_ABI_Ctest__component_CISimple_INTERFACE_DEFINED__) #define ____x_ABI_Ctest__component_CISimple_INTERFACE_DEFINED__ typedef struct __x_ABI_Ctest__component_CISimpleVtbl @@ -4445,6 +4495,73 @@ struct __x_ABI_Ctest__component_CStructWithIReference EXTERN_C const IID IID___x_ABI_Ctest__component_CIUnsealedDerivedOverrides; #endif /* !defined(____x_ABI_Ctest__component_CIUnsealedDerivedOverrides_INTERFACE_DEFINED__) */ +#if !defined(____x_ABI_Ctest__component_CIWeakReferencer_INTERFACE_DEFINED__) + #define ____x_ABI_Ctest__component_CIWeakReferencer_INTERFACE_DEFINED__ + typedef struct __x_ABI_Ctest__component_CIWeakReferencerVtbl + { + BEGIN_INTERFACE + + HRESULT (STDMETHODCALLTYPE* QueryInterface)(__x_ABI_Ctest__component_CIWeakReferencer* This, + REFIID riid, + void** ppvObject); + ULONG (STDMETHODCALLTYPE* AddRef)(__x_ABI_Ctest__component_CIWeakReferencer* This); + ULONG (STDMETHODCALLTYPE* Release)(__x_ABI_Ctest__component_CIWeakReferencer* This); + HRESULT (STDMETHODCALLTYPE* GetIids)(__x_ABI_Ctest__component_CIWeakReferencer* This, + ULONG* iidCount, + IID** iids); + HRESULT (STDMETHODCALLTYPE* GetRuntimeClassName)(__x_ABI_Ctest__component_CIWeakReferencer* This, + HSTRING* className); + HRESULT (STDMETHODCALLTYPE* GetTrustLevel)(__x_ABI_Ctest__component_CIWeakReferencer* This, + TrustLevel* trustLevel); + HRESULT (STDMETHODCALLTYPE* Resolve)(__x_ABI_Ctest__component_CIWeakReferencer* This, + __x_ABI_Ctest__component_CIReferenceTarget** result); + + END_INTERFACE + } __x_ABI_Ctest__component_CIWeakReferencerVtbl; + + interface __x_ABI_Ctest__component_CIWeakReferencer + { + CONST_VTBL struct __x_ABI_Ctest__component_CIWeakReferencerVtbl* lpVtbl; + }; + + + EXTERN_C const IID IID___x_ABI_Ctest__component_CIWeakReferencer; +#endif /* !defined(____x_ABI_Ctest__component_CIWeakReferencer_INTERFACE_DEFINED__) */ + +#if !defined(____x_ABI_Ctest__component_CIWeakReferencerFactory_INTERFACE_DEFINED__) + #define ____x_ABI_Ctest__component_CIWeakReferencerFactory_INTERFACE_DEFINED__ + typedef struct __x_ABI_Ctest__component_CIWeakReferencerFactoryVtbl + { + BEGIN_INTERFACE + + HRESULT (STDMETHODCALLTYPE* QueryInterface)(__x_ABI_Ctest__component_CIWeakReferencerFactory* This, + REFIID riid, + void** ppvObject); + ULONG (STDMETHODCALLTYPE* AddRef)(__x_ABI_Ctest__component_CIWeakReferencerFactory* This); + ULONG (STDMETHODCALLTYPE* Release)(__x_ABI_Ctest__component_CIWeakReferencerFactory* This); + HRESULT (STDMETHODCALLTYPE* GetIids)(__x_ABI_Ctest__component_CIWeakReferencerFactory* This, + ULONG* iidCount, + IID** iids); + HRESULT (STDMETHODCALLTYPE* GetRuntimeClassName)(__x_ABI_Ctest__component_CIWeakReferencerFactory* This, + HSTRING* className); + HRESULT (STDMETHODCALLTYPE* GetTrustLevel)(__x_ABI_Ctest__component_CIWeakReferencerFactory* This, + TrustLevel* trustLevel); + HRESULT (STDMETHODCALLTYPE* CreateInstance)(__x_ABI_Ctest__component_CIWeakReferencerFactory* This, + __x_ABI_Ctest__component_CIReferenceTarget* object, + __x_ABI_Ctest__component_CIWeakReferencer** value); + + END_INTERFACE + } __x_ABI_Ctest__component_CIWeakReferencerFactoryVtbl; + + interface __x_ABI_Ctest__component_CIWeakReferencerFactory + { + CONST_VTBL struct __x_ABI_Ctest__component_CIWeakReferencerFactoryVtbl* lpVtbl; + }; + + + EXTERN_C const IID IID___x_ABI_Ctest__component_CIWeakReferencerFactory; +#endif /* !defined(____x_ABI_Ctest__component_CIWeakReferencerFactory_INTERFACE_DEFINED__) */ + #if !defined(____x_ABI_Ctest__component_CInterfaceWithReturnDelegate_INTERFACE_DEFINED__) #define ____x_ABI_Ctest__component_CInterfaceWithReturnDelegate_INTERFACE_DEFINED__ typedef struct __x_ABI_Ctest__component_CInterfaceWithReturnDelegateVtbl diff --git a/tests/test_component/Sources/test_component/test_component+ABI.swift b/tests/test_component/Sources/test_component/test_component+ABI.swift index 11ae4a21..38ad32cd 100644 --- a/tests/test_component/Sources/test_component/test_component+ABI.swift +++ b/tests/test_component/Sources/test_component/test_component+ABI.swift @@ -119,6 +119,10 @@ private var IID___x_ABI_Ctest__component_CINullValuesStatics: test_component.IID .init(Data1: 0x4F2BB96B, Data2: 0xB91D, Data3: 0x51E5, Data4: ( 0xA5,0x89,0x26,0x52,0xC1,0x65,0xA8,0xB5 ))// 4F2BB96B-B91D-51E5-A589-2652C165A8B5 } +private var IID___x_ABI_Ctest__component_CIReferenceTarget: test_component.IID { + .init(Data1: 0x128E6AAA, Data2: 0xF772, Data3: 0x5A6F, Data4: ( 0x85,0x8B,0x3B,0x69,0x04,0x18,0xC8,0x73 ))// 128E6AAA-F772-5A6F-858B-3B690418C873 +} + private var IID___x_ABI_Ctest__component_CISimple: test_component.IID { .init(Data1: 0xAE7B4545, Data2: 0xD9D0, Data3: 0x5655, Data4: ( 0xB1,0xDE,0xA0,0x7D,0xA1,0x3B,0xD8,0x9B ))// AE7B4545-D9D0-5655-B1DE-A07DA13BD89B } @@ -191,6 +195,14 @@ private var IID___x_ABI_Ctest__component_CIUnsealedDerivedOverrides: test_compon .init(Data1: 0x828DCEE6, Data2: 0xF93A, Data3: 0x5A4D, Data4: ( 0xBC,0xEE,0xF7,0xC1,0xDE,0xE4,0xEB,0x4E ))// 828DCEE6-F93A-5A4D-BCEE-F7C1DEE4EB4E } +private var IID___x_ABI_Ctest__component_CIWeakReferencer: test_component.IID { + .init(Data1: 0xF3CE877F, Data2: 0x5BD2, Data3: 0x53C7, Data4: ( 0xAA,0x6A,0x39,0xF0,0x64,0x78,0x1C,0x21 ))// F3CE877F-5BD2-53C7-AA6A-39F064781C21 +} + +private var IID___x_ABI_Ctest__component_CIWeakReferencerFactory: test_component.IID { + .init(Data1: 0x34CE8191, Data2: 0x4DC4, Data3: 0x50EF, Data4: ( 0xB6,0x9E,0x19,0x8F,0x3C,0x9F,0x65,0x52 ))// 34CE8191-4DC4-50EF-B69E-198F3C9F6552 +} + private var IID___x_ABI_Ctest__component_CInterfaceWithReturnDelegate: test_component.IID { .init(Data1: 0xB0EBC406, Data2: 0x17C0, Data3: 0x5703, Data4: ( 0xB9,0xC7,0x50,0xBE,0x67,0x5B,0xBC,0x95 ))// B0EBC406-17C0-5703-B9C7-50BE675BBC95 } @@ -1701,6 +1713,55 @@ public enum __ABI_test_component { } + public class IReferenceTarget: test_component.IInspectable { + override public class var IID: test_component.IID { IID___x_ABI_Ctest__component_CIReferenceTarget } + + open func MethodImpl() throws { + _ = try perform(as: __x_ABI_Ctest__component_CIReferenceTarget.self) { pThis in + try CHECKED(pThis.pointee.lpVtbl.pointee.Method(pThis)) + } + } + + } + + internal static var IReferenceTargetVTable: __x_ABI_Ctest__component_CIReferenceTargetVtbl = .init( + QueryInterface: { IReferenceTargetWrapper.queryInterface($0, $1, $2) }, + AddRef: { IReferenceTargetWrapper.addRef($0) }, + Release: { IReferenceTargetWrapper.release($0) }, + GetIids: { + let size = MemoryLayout.size + let iids = CoTaskMemAlloc(UInt64(size) * 3).assumingMemoryBound(to: test_component.IID.self) + iids[0] = IUnknown.IID + iids[1] = IInspectable.IID + iids[2] = __ABI_test_component.IReferenceTargetWrapper.IID + $1!.pointee = 3 + $2!.pointee = iids + return S_OK + }, + + GetRuntimeClassName: { + _ = $0 + let hstring = try! HString("test_component.IReferenceTarget").detach() + $1!.pointee = hstring + return S_OK + }, + + GetTrustLevel: { + _ = $0 + $1!.pointee = TrustLevel(rawValue: 0) + return S_OK + }, + + Method: { + do { + guard let __unwrapped__instance = IReferenceTargetWrapper.tryUnwrapFrom(raw: $0) else { return E_INVALIDARG } + try __unwrapped__instance.method() + return S_OK + } catch { return failWith(err: E_FAIL) } + } + ) + + public typealias IReferenceTargetWrapper = InterfaceWrapperBase<__IMPL_test_component.IReferenceTargetBridge> public class ISimple: test_component.IInspectable { override public class var IID: test_component.IID { IID___x_ABI_Ctest__component_CISimple } @@ -2229,6 +2290,36 @@ public enum __ABI_test_component { } + public class IWeakReferencer: test_component.IInspectable { + override public class var IID: test_component.IID { IID___x_ABI_Ctest__component_CIWeakReferencer } + + internal func ResolveImpl() throws -> test_component.AnyIReferenceTarget? { + let (result) = try ComPtrs.initialize { resultAbi in + _ = try perform(as: __x_ABI_Ctest__component_CIWeakReferencer.self) { pThis in + try CHECKED(pThis.pointee.lpVtbl.pointee.Resolve(pThis, &resultAbi)) + } + } + return __ABI_test_component.IReferenceTargetWrapper.unwrapFrom(abi: result) + } + + } + + public class IWeakReferencerFactory: test_component.IInspectable { + override public class var IID: test_component.IID { IID___x_ABI_Ctest__component_CIWeakReferencerFactory } + + internal func CreateInstanceImpl(_ object: test_component.AnyIReferenceTarget?) throws -> IWeakReferencer { + let (value) = try ComPtrs.initialize { valueAbi in + let objectWrapper = __ABI_test_component.IReferenceTargetWrapper(object) + let _object = try! objectWrapper?.toABI { $0 } + _ = try perform(as: __x_ABI_Ctest__component_CIWeakReferencerFactory.self) { pThis in + try CHECKED(pThis.pointee.lpVtbl.pointee.CreateInstance(pThis, _object, &valueAbi)) + } + } + return IWeakReferencer(value!) + } + + } + public class InterfaceWithReturnDelegate: test_component.IInspectable { override public class var IID: test_component.IID { IID___x_ABI_Ctest__component_CInterfaceWithReturnDelegate } diff --git a/tests/test_component/Sources/test_component/test_component+Impl.swift b/tests/test_component/Sources/test_component/test_component+Impl.swift index d70576fc..17f2b1cf 100644 --- a/tests/test_component/Sources/test_component/test_component+Impl.swift +++ b/tests/test_component/Sources/test_component/test_component+Impl.swift @@ -223,6 +223,35 @@ public enum __IMPL_test_component { } + public enum IReferenceTargetBridge : AbiInterfaceBridge { + public typealias CABI = __x_ABI_Ctest__component_CIReferenceTarget + public typealias SwiftABI = __ABI_test_component.IReferenceTarget + public typealias SwiftProjection = AnyIReferenceTarget + public static func from(abi: ComPtr?) -> SwiftProjection? { + guard let abi = abi else { return nil } + return IReferenceTargetImpl(abi) + } + + public static func makeAbi() -> CABI { + let vtblPtr = withUnsafeMutablePointer(to: &__ABI_test_component.IReferenceTargetVTable) { $0 } + return .init(lpVtbl: vtblPtr) + } + } + + fileprivate class IReferenceTargetImpl: IReferenceTarget, WinRTAbiImpl { + fileprivate typealias Bridge = IReferenceTargetBridge + fileprivate let _default: Bridge.SwiftABI + fileprivate var thisPtr: test_component.IInspectable { _default } + fileprivate init(_ fromAbi: ComPtr) { + _default = Bridge.SwiftABI(fromAbi) + } + + fileprivate func method() throws { + try _default.MethodImpl() + } + + } + public enum ISimpleDelegateBridge : AbiInterfaceBridge { public typealias CABI = __x_ABI_Ctest__component_CISimpleDelegate public typealias SwiftABI = __ABI_test_component.ISimpleDelegate diff --git a/tests/test_component/Sources/test_component/test_component+MakeFromAbi.swift b/tests/test_component/Sources/test_component/test_component+MakeFromAbi.swift index d1aae6a0..fc034f19 100644 --- a/tests/test_component/Sources/test_component/test_component+MakeFromAbi.swift +++ b/tests/test_component/Sources/test_component/test_component+MakeFromAbi.swift @@ -183,6 +183,11 @@ fileprivate func makeIInterfaceWithObservableVectorFrom(abi: test_component.IIns return __IMPL_test_component.IInterfaceWithObservableVectorBridge.from(abi: RawPointer(swiftAbi))! } +fileprivate func makeIReferenceTargetFrom(abi: test_component.IInspectable) -> Any { + let swiftAbi: __ABI_test_component.IReferenceTarget = try! abi.QueryInterface() + return __IMPL_test_component.IReferenceTargetBridge.from(abi: RawPointer(swiftAbi))! +} + fileprivate func makeISimpleDelegateFrom(abi: test_component.IInspectable) -> Any { let swiftAbi: __ABI_test_component.ISimpleDelegate = try! abi.QueryInterface() return __IMPL_test_component.ISimpleDelegateBridge.from(abi: RawPointer(swiftAbi))! @@ -387,6 +392,10 @@ fileprivate func makeUnsealedDerivedNoOverridesFrom(abi: test_component.IInspect return UnsealedDerivedNoOverrides(fromAbi: abi) } +fileprivate func makeWeakReferencerFrom(abi: test_component.IInspectable) -> Any { + return WeakReferencer(fromAbi: abi) +} + @_spi(__MakeFromAbi_DoNotImport) public class __MakeFromAbi: MakeFromAbi { public static func from(typeName: String, abi: test_component.IInspectable) -> Any? { @@ -427,6 +436,7 @@ public class __MakeFromAbi: MakeFromAbi { case "IBasic": return makeIBasicFrom(abi: abi) case "IIAmImplementable": return makeIIAmImplementableFrom(abi: abi) case "IInterfaceWithObservableVector": return makeIInterfaceWithObservableVectorFrom(abi: abi) + case "IReferenceTarget": return makeIReferenceTargetFrom(abi: abi) case "ISimpleDelegate": return makeISimpleDelegateFrom(abi: abi) case "InterfaceWithReturnDelegate": return makeInterfaceWithReturnDelegateFrom(abi: abi) case "WithIterableGuids": return makeWithIterableGuidsFrom(abi: abi) @@ -477,6 +487,7 @@ public class __MakeFromAbi: MakeFromAbi { case "UnsealedDerivedFromNoConstructor": return makeUnsealedDerivedFromNoConstructorFrom(abi: abi) case "UnsealedDerivedNoConstructor": return makeUnsealedDerivedNoConstructorFrom(abi: abi) case "UnsealedDerivedNoOverrides": return makeUnsealedDerivedNoOverridesFrom(abi: abi) + case "WeakReferencer": return makeWeakReferencerFrom(abi: abi) default: return nil } } diff --git a/tests/test_component/Sources/test_component/test_component.swift b/tests/test_component/Sources/test_component/test_component.swift index 7e71f720..b5e5b2cb 100644 --- a/tests/test_component/Sources/test_component/test_component.swift +++ b/tests/test_component/Sources/test_component/test_component.swift @@ -1645,6 +1645,43 @@ open class UnsealedDerivedNoOverrides : test_component.BaseNoOverrides { } } +public final class WeakReferencer : WinRTClass { + private typealias SwiftABI = __ABI_test_component.IWeakReferencer + private typealias CABI = __x_ABI_Ctest__component_CIWeakReferencer + private lazy var _default: SwiftABI! = getInterfaceForCaching() + @_spi(WinRTInternal) + override public func _getABI() -> UnsafeMutablePointer? { + if T.self == CABI.self { + return RawPointer(_default) + } + return super._getABI() + } + + @_spi(WinRTInternal) + public static func from(abi: ComPtr<__x_ABI_Ctest__component_CIWeakReferencer>?) -> WeakReferencer? { + guard let abi = abi else { return nil } + return .init(fromAbi: test_component.IInspectable(abi)) + } + + @_spi(WinRTInternal) + public init(fromAbi: test_component.IInspectable) { + super.init(fromAbi) + } + + private static let _IWeakReferencerFactory: __ABI_test_component.IWeakReferencerFactory = try! RoGetActivationFactory("test_component.WeakReferencer") + public init(_ object: AnyIReferenceTarget!) { + super.init(try! Self._IWeakReferencerFactory.CreateInstanceImpl(object)) + } + + public func resolve() throws -> AnyIReferenceTarget! { + try _default.ResolveImpl() + } + + deinit { + _default = nil + } +} + public typealias ObjectHandler = (Any?) throws -> () public typealias VoidToVoidDelegate = () throws -> () public struct BlittableStruct: Hashable, Codable { @@ -1833,6 +1870,22 @@ extension IInterfaceWithObservableVector { } public typealias AnyIInterfaceWithObservableVector = any IInterfaceWithObservableVector +public protocol IReferenceTarget : WinRTInterface { + func method() throws +} + +extension IReferenceTarget { + public func queryInterface(_ iid: test_component.IID) -> IUnknownRef? { + switch iid { + case __ABI_test_component.IReferenceTargetWrapper.IID: + let wrapper = __ABI_test_component.IReferenceTargetWrapper(self) + return wrapper!.queryInterface(iid) + default: return nil + } + } +} +public typealias AnyIReferenceTarget = any IReferenceTarget + public protocol ISimpleDelegate : WinRTInterface { func doThis() throws func doThat(_ val: Int32) throws diff --git a/tests/test_component/cpp/CMakeLists.txt b/tests/test_component/cpp/CMakeLists.txt index 370ae6f8..6dcb0ada 100644 --- a/tests/test_component/cpp/CMakeLists.txt +++ b/tests/test_component/cpp/CMakeLists.txt @@ -135,6 +135,7 @@ target_sources(test_component_cpp PRIVATE UnsealedDerivedNoOverrides.cpp UnsealedDerivedFromNoConstructor.cpp UnsealedDerivedNoConstructor.cpp + WeakReferencer.cpp exports.def #Windows.Class.cpp ${MIDL_FILE} diff --git a/tests/test_component/cpp/WeakReferencer.cpp b/tests/test_component/cpp/WeakReferencer.cpp new file mode 100644 index 00000000..9f6ec1d3 --- /dev/null +++ b/tests/test_component/cpp/WeakReferencer.cpp @@ -0,0 +1,15 @@ +#include "pch.h" +#include "WeakReferencer.h" +#include "WeakReferencer.g.cpp" + +namespace winrt::test_component::implementation +{ + WeakReferencer::WeakReferencer(test_component::IReferenceTarget const& object) + { + this->target = winrt::make_weak(object); + } + test_component::IReferenceTarget WeakReferencer::Resolve() + { + return target.get(); + } +} diff --git a/tests/test_component/cpp/WeakReferencer.h b/tests/test_component/cpp/WeakReferencer.h new file mode 100644 index 00000000..34601fa3 --- /dev/null +++ b/tests/test_component/cpp/WeakReferencer.h @@ -0,0 +1,22 @@ +#pragma once +#include "WeakReferencer.g.h" + +namespace winrt::test_component::implementation +{ + struct WeakReferencer : WeakReferencerT + { + WeakReferencer() = default; + + WeakReferencer(test_component::IReferenceTarget const& object); + test_component::IReferenceTarget Resolve(); + + private: + winrt::weak_ref target; + }; +} +namespace winrt::test_component::factory_implementation +{ + struct WeakReferencer : WeakReferencerT + { + }; +} diff --git a/tests/test_component/cpp/WeakReferencer.idl b/tests/test_component/cpp/WeakReferencer.idl new file mode 100644 index 00000000..300bd16f --- /dev/null +++ b/tests/test_component/cpp/WeakReferencer.idl @@ -0,0 +1,13 @@ +namespace test_component +{ + interface IReferenceTarget + { + void Method(); + } + + runtimeclass WeakReferencer + { + WeakReferencer(IReferenceTarget object); + IReferenceTarget Resolve(); + } +} diff --git a/tests/test_component/cpp/test_component.idl b/tests/test_component/cpp/test_component.idl index 1db9f489..c8da39d3 100644 --- a/tests/test_component/cpp/test_component.idl +++ b/tests/test_component/cpp/test_component.idl @@ -4,6 +4,7 @@ #include "EventTester.idl" #include "Keywords.idl" #include "NullValues.idl" +#include "WeakReferencer.idl" import "Windows.Foundation.idl"; // import "Windows.Foundation.Numerics.idl";