为什么这个dynamic_cast<T>不起作用?
Why is this dynamic_cast<T> not working?
这应该非常简单。ID2D1LinearGradientBrush来源于ID2D1Brush和一个有效的变量表。我意识到QueryInterface可以在这里工作,但是我的问题与dynamic_cast有关。
[definition from d2d1.h]
interface DX_DECLARE_INTERFACE("2cd906ab-12e2-11dc-9fed-001143a055f9")
ID2D1LinearGradientBrush : public ID2D1Brush
{
// ....
}
然而,考虑到过于简化的示例函数…
bool ClampToItem(ID2D1Brush *brush, SizeF itemSize)
{
// As expected, works when a linear gradient brush is the parameter.
ID2D1LinearGradientBrush *linearGradientBrush = static_cast<ID2D1LinearGradientBrush *>(brush);
linearGradientBrush->SetStartPoint(D2D1_POINT_2F{ itemSize.Width, 0.0f });
linearGradientBrush->SetEndPoint(D2D1_POINT_2F{ itemSize.Width, itemSize.Height });
return true;
}
bool ClampToItem2(ID2D1Brush *brush, SizeF itemSize)
{
// this dynamic cast FAILS EVERY TIME with an access violation
ID2D1LinearGradientBrush *linearGradientBrush = dynamic_cast<ID2D1LinearGradientBrush *>(brush);
if (!linearGradientBrush) // <-- never gets here
return false;
linearGradientBrush->SetStartPoint(D2D1_POINT_2F{ itemSize.Width, 0.0f });
linearGradientBrush->SetEndPoint(D2D1_POINT_2F{ itemSize.Width, itemSize.Height });
return true;
}
因为我不确定是否将ID2D1LinearGradientBrush作为参数提供,所以我想使用dynamic_cast。我一定错过了一些简单的东西。这些COM对象不包含RTTI信息吗?谢谢你的帮助。
// For clarification, this works as expected
bool ClampToItem3(ID2D1Brush *brush, SizeF itemSize)
{
ID2D1LinearGradientBrush *linearGradientBrush;
HRESULT hr = brush->QueryInterface(__uuidof(ID2D1LinearGradientBrush), (void **)&linearGradientBrush);
if (hr == S_OK)
{
linearGradientBrush->SetStartPoint(D2D1_POINT_2F{ itemSize.Width, 0.0f });
linearGradientBrush->SetEndPoint(D2D1_POINT_2F{ itemSize.Width, itemSize.Height });
linearGradientBrush->Release();
linearGradientBrush = nullptr;
}
return true;
}
编辑:跟踪到动态强制转换(到rtti.cpp):
extern "C" PVOID __CLRCALL_OR_CDECL __RTDynamicCast(
PVOID inptr, // Pointer to polymorphic object
LONG VfDelta, // Offset of vfptr in object
PVOID SrcType, // Static type of object pointed to by inptr
PVOID TargetType, // Desired result of cast
BOOL isReference) // TRUE if input is reference, FALSE if input is ptr
throw(...)
被调用,inptr是有效的,vfDelta是0,SrcType和TargetType看起来很棒,isRef表示false。进一步跟踪,内存访问冲突发生在这里:
// Ptr to CompleteObjectLocator should be stored at vfptr[-1]
_RTTICompleteObjectLocator *pCompleteLocator =
(_RTTICompleteObjectLocator *) ((*((void***)inptr))[-1]);
char *pCompleteObject = (char *)inptr - COL_OFFSET(*pCompleteLocator);
由于*pCompleteLocator被移动到一个无效的位置。
来自Microsoft的标准COM接口使用__declspec(novtable)
作为其定义的一部分;如果你看一下DX_DECLARE_INTERFACE
的定义,你会发现这就是这种情况。这意味着基接口类没有变量表,只有具体实现才有。RTTI没有dynamic_cast
正常工作所需的信息
对于COM接口,您应该始终使用QueryInterface
来进行动态强制转换。
相关文章:
- 我的神经网络不起作用 [XOR 问题]
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- C++为什么尽管我调用了void函数,它却不起作用
- 为什么在保护模式下继承升级不起作用
- 循环在计数器中不起作用
- 在其他文件中创建类时在 c++ 项目中不起作用
- Visual studio代码重构似乎不起作用(例如,重命名符号-f2)
- 为什么二进制搜索在我的测试中不起作用
- 我的代码中有错误吗?使用BGI图形的C++代码对我不起作用
- 为什么 const std::p air<K,V>& 在 std::map 上基于范围的 for 循环不起作用?
- 带有指定长度字符* 参数的 std::regex_search 在 VS2017 中不起作用?
- Bjarne Stroustrup Book - std_lib_facilities.h - 不起作用(未知类型名称)
- 为什么简单的算术减法在"if"条件下不起作用?
- 为什么Stroustup书中的has_f不起作用
- 你能检查一下为什么在这个代码中从链接列表中删除项目不起作用吗
- 嵌套While循环不起作用(C++问题)
- C++Matching Brackets 2解决方案不起作用
- 为什么这段代码不起作用,我该如何解决?
- 我正在开发服务器,ip作为参数传递不起作用