From 280cce125d6de16ee616f6173cc10a2c9d12e3f8 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Wed, 10 Oct 2018 21:24:10 +0300 Subject: [PATCH] Fixed vtable layout --- src/Avalonia.Native.OSX/Screens.mm | 1 + src/Avalonia.Native.OSX/SystemDialogs.mm | 2 ++ src/Avalonia.Native.OSX/clipboard.mm | 1 + src/Avalonia.Native.OSX/cursor.h | 1 + src/Avalonia.Native.OSX/cursor.mm | 1 + src/Avalonia.Native.OSX/main.mm | 2 ++ src/Avalonia.Native.OSX/platformthreading.mm | 2 ++ src/Avalonia.Native.OSX/window.mm | 27 +++++++++++++++++--- src/headers/avalonia-native.h | 22 ++++++++-------- src/headers/com.h | 17 ++++++++++++ 10 files changed, 61 insertions(+), 15 deletions(-) diff --git a/src/Avalonia.Native.OSX/Screens.mm b/src/Avalonia.Native.OSX/Screens.mm index bf6cb46e27..229c598797 100644 --- a/src/Avalonia.Native.OSX/Screens.mm +++ b/src/Avalonia.Native.OSX/Screens.mm @@ -6,6 +6,7 @@ class Screens : public ComSingleObject { public: + FORWARD_IUNKNOWN() virtual HRESULT GetScreenCount (int* ret) { @autoreleasepool diff --git a/src/Avalonia.Native.OSX/SystemDialogs.mm b/src/Avalonia.Native.OSX/SystemDialogs.mm index e67df996f8..55b1abc720 100644 --- a/src/Avalonia.Native.OSX/SystemDialogs.mm +++ b/src/Avalonia.Native.OSX/SystemDialogs.mm @@ -6,6 +6,8 @@ class SystemDialogs : public ComSingleObject { +public: + FORWARD_IUNKNOWN() virtual void SelectFolderDialog (IAvnWindow* parentWindowHandle, IAvnSystemDialogEvents* events, const char* title, diff --git a/src/Avalonia.Native.OSX/clipboard.mm b/src/Avalonia.Native.OSX/clipboard.mm index 5c0f483d98..e39b78fc33 100644 --- a/src/Avalonia.Native.OSX/clipboard.mm +++ b/src/Avalonia.Native.OSX/clipboard.mm @@ -6,6 +6,7 @@ class Clipboard : public ComSingleObject { public: + FORWARD_IUNKNOWN() virtual HRESULT GetText (void** retOut) { @autoreleasepool diff --git a/src/Avalonia.Native.OSX/cursor.h b/src/Avalonia.Native.OSX/cursor.h index aefbfbb15f..a8eb49c0b9 100644 --- a/src/Avalonia.Native.OSX/cursor.h +++ b/src/Avalonia.Native.OSX/cursor.h @@ -13,6 +13,7 @@ private: NSCursor * _native; public: + FORWARD_IUNKNOWN() Cursor(NSCursor * cursor) { _native = cursor; diff --git a/src/Avalonia.Native.OSX/cursor.mm b/src/Avalonia.Native.OSX/cursor.mm index 64ffb38849..6a06918527 100644 --- a/src/Avalonia.Native.OSX/cursor.mm +++ b/src/Avalonia.Native.OSX/cursor.mm @@ -50,6 +50,7 @@ class CursorFactory : public ComSingleObject { public: + FORWARD_IUNKNOWN() virtual HRESULT SetShowInDock(int show) { ShowInDock = show; @@ -62,6 +63,7 @@ class AvaloniaNative : public ComSingleObject { public: + FORWARD_IUNKNOWN() bool Cancelled = 0; virtual void Cancel() { @@ -69,6 +70,7 @@ private: }; public: + FORWARD_IUNKNOWN() ComPtr SignaledCallback; PlatformThreadingInterface() diff --git a/src/Avalonia.Native.OSX/window.mm b/src/Avalonia.Native.OSX/window.mm index e5ce0977cb..3dcfef20bb 100644 --- a/src/Avalonia.Native.OSX/window.mm +++ b/src/Avalonia.Native.OSX/window.mm @@ -6,17 +6,20 @@ #include "KeyTransform.h" #include "cursor.h" -class WindowBaseImpl : public ComSingleObject, public INSWindowHolder +class WindowBaseImpl : public virtual ComSingleObject, public INSWindowHolder { private: NSCursor* cursor; public: + FORWARD_IUNKNOWN() AvnView* View; AvnWindow* Window; ComPtr BaseEvents; AvnPoint lastPositionSet; + + WindowBaseImpl(IAvnWindowBaseEvents* events) { BaseEvents = events; @@ -785,7 +788,7 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent }*/ @end -class PopupImpl : public WindowBaseImpl, public IAvnPopup +class PopupImpl : public virtual WindowBaseImpl, public IAvnPopup { private: BEGIN_INTERFACE_MAP() @@ -847,7 +850,7 @@ public: } }; -class WindowImpl : public WindowBaseImpl, public IAvnWindow, public IWindowStateChanged +class WindowImpl : public virtual WindowBaseImpl, public virtual IAvnWindow, public IWindowStateChanged { private: bool _canResize = true; @@ -859,6 +862,12 @@ private: INHERIT_INTERFACE_MAP(WindowBaseImpl) INTERFACE_MAP_ENTRY(IAvnWindow, IID_IAvnWindow) END_INTERFACE_MAP() + + virtual uint Release() + { + return ComObject::Release(); + } + ComPtr WindowEvents; WindowImpl(IAvnWindowEvents* events) : WindowBaseImpl(events) { @@ -1035,11 +1044,21 @@ protected: } }; +typedef void (*pfnvoid)(); + +struct vtable +{ + pfnvoid entries[30]; +}; + extern IAvnWindow* CreateAvnWindow(IAvnWindowEvents*events) { @autoreleasepool { - IAvnWindow* ptr = dynamic_cast(new WindowImpl(events)); + IAvnWindow* ptr = (IAvnWindow*)new WindowImpl(events); + auto vt = *(vtable**)(void*)ptr; + + return ptr; } } diff --git a/src/headers/avalonia-native.h b/src/headers/avalonia-native.h index eaa0571e7b..a2c4a22eab 100644 --- a/src/headers/avalonia-native.h +++ b/src/headers/avalonia-native.h @@ -140,7 +140,7 @@ enum AvnWindowEdge WindowEdgeSouthEast }; -AVNCOM(IAvaloniaNativeFactory, 01) : virtual IUnknown +AVNCOM(IAvaloniaNativeFactory, 01) : IUnknown { public: virtual HRESULT Initialize() = 0; @@ -154,7 +154,7 @@ public: virtual HRESULT CreateCursorFactory(IAvnCursorFactory** ppv) = 0; }; -AVNCOM(IAvnWindowBase, 02) : virtual IUnknown +AVNCOM(IAvnWindowBase, 02) : IUnknown { virtual HRESULT Show() = 0; virtual HRESULT Hide () = 0; @@ -216,7 +216,7 @@ AVNCOM(IAvnWindowEvents, 06) : IAvnWindowBaseEvents virtual void WindowStateChanged (AvnWindowState state) = 0; }; -AVNCOM(IAvnMacOptions, 07) : virtual IUnknown +AVNCOM(IAvnMacOptions, 07) : IUnknown { virtual HRESULT SetShowInDock(int show) = 0; }; @@ -231,12 +231,12 @@ AVNCOM(IAvnSignaledCallback, 09) : IUnknown virtual void Signaled(int priority, bool priorityContainsMeaningfulValue) = 0; }; -AVNCOM(IAvnLoopCancellation, 0a) : virtual IUnknown +AVNCOM(IAvnLoopCancellation, 0a) : IUnknown { virtual void Cancel() = 0; }; -AVNCOM(IAvnPlatformThreadingInterface, 0b) : virtual IUnknown +AVNCOM(IAvnPlatformThreadingInterface, 0b) : IUnknown { virtual bool GetCurrentThreadIsLoopThread() = 0; virtual void SetSignaledCallback(IAvnSignaledCallback* cb) = 0; @@ -247,12 +247,12 @@ AVNCOM(IAvnPlatformThreadingInterface, 0b) : virtual IUnknown virtual IUnknown* StartTimer(int priority, int ms, IAvnActionCallback* callback) = 0; }; -AVNCOM(IAvnSystemDialogEvents, 0c) : virtual IUnknown +AVNCOM(IAvnSystemDialogEvents, 0c) : IUnknown { virtual void OnCompleted (int numResults, void* ptrFirstResult) = 0; }; -AVNCOM(IAvnSystemDialogs, 0d) : virtual IUnknown +AVNCOM(IAvnSystemDialogs, 0d) : IUnknown { virtual void SelectFolderDialog (IAvnWindow* parentWindowHandle, IAvnSystemDialogEvents* events, @@ -275,24 +275,24 @@ AVNCOM(IAvnSystemDialogs, 0d) : virtual IUnknown const char* filters) = 0; }; -AVNCOM(IAvnScreens, 0e) : virtual IUnknown +AVNCOM(IAvnScreens, 0e) : IUnknown { virtual HRESULT GetScreenCount (int* ret) = 0; virtual HRESULT GetScreen (int index, AvnScreen* ret) = 0; }; -AVNCOM(IAvnClipboard, 0f) : virtual IUnknown +AVNCOM(IAvnClipboard, 0f) : IUnknown { virtual HRESULT GetText (void** retOut) = 0; virtual HRESULT SetText (char* text) = 0; virtual HRESULT Clear() = 0; }; -AVNCOM(IAvnCursor, 10) : virtual IUnknown +AVNCOM(IAvnCursor, 10) : IUnknown { }; -AVNCOM(IAvnCursorFactory, 11) : virtual IUnknown +AVNCOM(IAvnCursorFactory, 11) : IUnknown { virtual HRESULT GetCursor (AvnStandardCursorType cursorType, IAvnCursor** retOut) = 0; }; diff --git a/src/headers/com.h b/src/headers/com.h index 728cec3e05..f6ba6a4151 100644 --- a/src/headers/com.h +++ b/src/headers/com.h @@ -107,13 +107,30 @@ public: }; +#define FORWARD_IUNKNOWN() \ +virtual ULONG Release(){ \ +return ComObject::Release(); \ +} \ +virtual ULONG AddRef() \ +{ \ + return ComObject::AddRef(); \ +} \ +virtual HRESULT QueryInterface(REFIID riid, void **ppvObject) \ +{ \ + return ComObject::QueryInterface(riid, ppvObject); \ +} + #define BEGIN_INTERFACE_MAP() public: virtual HRESULT STDMETHODCALLTYPE QueryInterfaceImpl(REFIID riid, void **ppvObject){ #define INTERFACE_MAP_ENTRY(TInterface, IID) if(0 == memcmp(riid, &IID, sizeof(GUID))) { TInterface* casted = this; *ppvObject = casted; return S_OK; } #define END_INTERFACE_MAP() return E_NOINTERFACE; } #define INHERIT_INTERFACE_MAP(TBase) if(TBase::QueryInterfaceImpl(riid, ppvObject) == S_OK) return S_OK; + + class ComUnknownObject : public ComObject { +public: + FORWARD_IUNKNOWN() virtual ::HRESULT STDMETHODCALLTYPE QueryInterfaceImpl(REFIID riid, void **ppvObject) override { return E_NOINTERFACE;