Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: Inheriting winrt::implements can't get weak_ref #1453

Closed
shuangshu opened this issue Nov 18, 2024 · 4 comments
Closed

Bug: Inheriting winrt::implements can't get weak_ref #1453

shuangshu opened this issue Nov 18, 2024 · 4 comments

Comments

@shuangshu
Copy link

shuangshu commented Nov 18, 2024

Version

No response

Summary

Inheriting winrt::implements can't get weak_ref
'static_cast' : cannot convert from 'winrt::impl::producer<T,IMyComInterface1,void> *' to 'T *'
how to resolve this error

Reproducible example

#include <crtdbg.h>
#include <unknwn.h>
#include "catch.hpp"
#include "winrt/base.h"

struct __declspec(uuid("ddc36e02-18ac-47c4-ae17-d420eece2281")) IMyComInterface1
	: ::IUnknown {
	virtual HRESULT Call1() = 0;
};

struct MyCoclass : winrt::implements<MyCoclass, IMyComInterface1> {
	HRESULT Call1() override {
		return S_OK;
	}
	virtual ~MyCoclass()
	{
	}

	virtual HRESULT Invoke()
	{
		return NOERROR;
	}
};

struct MyCoclass2 : winrt::implements<MyCoclass2, MyCoclass>
{
	virtual ~MyCoclass2()
	{
	}

	HRESULT Invoke() override
	{
		return NOERROR;
	}
};

int main(int const argc, char** argv)
{
   init_apartment();
   {
	auto mycoclass_instance{ winrt::make_self<MyCoclass2>() };
	winrt::weak_ref<MyCoclass2> weak(mycoclass_instance);
	auto weakval = weak.get();
   }
}

Expected behavior

No response

Actual behavior

No response

Additional comments

No response

@sylveon
Copy link
Contributor

sylveon commented Nov 18, 2024

This looks like #1312. Is your cppwinrt up to date?

@dmachaj
Copy link
Contributor

dmachaj commented Nov 18, 2024

I don't have a good understanding of this area but it seems like the inheritance is confusing things. If I change your example to this then it compiles for me. The change is to modify the type signature of the weak reference from winrt::weak_ref<MyCoclass2> to winrt::weak_ref<MyCoclass>.

int main(int const, char**)
{
	winrt::init_apartment();
	{
		auto mycoclass_instance{ winrt::make_self<MyCoclass2>() };
		winrt::weak_ref<MyCoclass> weak(mycoclass_instance);
		auto weakval = weak.get();
	}
}

I was able to repro the break on the latest stable release of cppwinrt (April 2024). I did have to tweak a few things in your code sample to get it to compile (e.g. arguments to main were unused and warning treated as error made that a break).

@sylveon
Copy link
Contributor

sylveon commented Nov 18, 2024

One problem is the presence of two winrt::implements in the inheritance hierarchy. There should only be one.

I'd remove it from MyCoClass2, in favor of directly inheriting from MyCoClass.

But even removing that, it won't compile.

The repro can also be changed to avoid weak_ref and make it clearer the problem is in get_self):

int main(int const argc, char** argv)
{
	winrt::init_apartment();
	{
		auto mycoclass_instance{ winrt::make<MyCoclass2>() };
		winrt::get_self<MyCoclass2>(mycoclass_instance);
	}
}

@shuangshu
Copy link
Author

shuangshu commented Nov 19, 2024

一个问题是继承层次结构中存在两个 winrt::implements。应该只有一个。

我会将其从 MyCoClass2 中删除,以便直接从 MyCoClass 继承。

但即使删除它,它也无法编译。

还可以更改再现以避免问题weak_ref并使其更清楚地表明问题出在get_self:)

int main(int const argc, char** argv)
{
winrt::init_apartment();
{
auto mycoclass_instance{ winrt::make() };
winrt::get_self(mycoclass_instance);
}
}

yes the problem is get_self

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants