使用从 WinRT 网格类派生的抽象类时,CastToBase 未解决的外部符号错误?

Posted

技术标签:

【中文标题】使用从 WinRT 网格类派生的抽象类时,CastToBase 未解决的外部符号错误?【英文标题】:CastToBase unresolved external symbol error when using abstract class derived from WinRT Grid Class? 【发布时间】:2017-12-14 08:56:09 【问题描述】:

这是我发现使用 C++/CX 时非常奇怪的事情。

鉴于以下情况:

ref class Duper : public Windows::UI::Xaml::Controls::Grid
internal:
    Duper()
    virtual void doNothing() = 0;
public:
    virtual ~Duper()

;

ref class Sub : public Duper

internal:
    Sub()
    void doNothing()override
public:
    virtual ~Sub()
;

调用子类:

Sub^ test = ref new Sub();
test->doNothing();

工作正常,但运行时:

Sub^ test = ref new Sub();
test->Width = 20;

您会收到类似于此的问候错误

Error   226 error LNK2001: unresolved external symbol "public: class Windows::UI::Xaml::Controls::Grid ^ __stdcall XSideView::__abi_CastToBase(void)" (?__abi_CastToBase@XSideView@@Q$AAGP$AAVGrid@Controls@Xaml@UI@Windows@@XZ)    D:\OZSOURCE70\OZReportViewer\OZWRTViewer\ozrv\platform.lib(OZCViewerSideView.obj)   ozrv_dll

但是,您可以通过这样做绕过调用 CastToBase:

Grid^ base = dynamic_cast<Grid^>(test3);
base->Width = 30;

它会正常工作的。

有人可以向我解释为什么会发生这种情况吗?除了每次使用此类时显式转换为 Grid 类之外,还有其他方法可以解决此问题吗?虽然我没有费心用其他 ref 类进行测试,但我敢打赌他们会遇到类似的问题。

PS:这可能是一个错误,并已在以后的版本中修复(我目前正在使用 VS2013 在 Windows 8.1 中开发)

PPS:CastToBase 文档:https://docs.microsoft.com/en-us/cpp/windows/interfacetraits-casttobase-method

【问题讨论】:

【参考方案1】:

WinRT 没有抽象类的概念——这是一种 C++ 主义。您可以使用接口(如果它是 100% 抽象的)或在基类中实现方法,例如:

virtual void doNothing() 

  throw ref new Platform::FailureException(L"Can't use Duper directly"); 

(或恢复为dynamic_cast&lt;&gt; 技巧)。

【讨论】:

在调试构建时抛出异常是我最终要做的,因为我真正想要的是强制未来的开发人员重写该方法。尽管如此,我还是对 C++CX 与 C++ 概念不太兼容感到有些恼火。 ref 类必须遵守 WinRT 类型的规则...所有其他代码都可以是“普通”C++

以上是关于使用从 WinRT 网格类派生的抽象类时,CastToBase 未解决的外部符号错误?的主要内容,如果未能解决你的问题,请参考以下文章

Typescript派生类和抽象类

当有多个派生类时,如何使用基类指针访问派生类的函数成员?

static_cast和dynamic_cast详解

使用Boost将派生类部分反序列化为基类时输入流错误

static_cast 派生类的接口

派生类时python abc subclasshook没有效果