动态转换意外地为类型返回null,但有时仅返回其他类型

时间:2022-04-05 17:06:22

I have this dynamic cast, which I would expect to always work:

我有这种动态演员,我希望它总能奏效:

BaseClass *b = new DerivedClass();
DerivedClass *d = dynamic_cast<DerivedClass *>(b);

Well, of course I'm posting this question because it doesn't always work. Here's the situation:

好吧,当然我发布这个问题是因为它并不总是有效。这是情况:

  • BaseClass and DerivedClass are both defined in the same framework.
  • BaseClass和DerivedClass都在同一框架中定义。

  • This framework is used in two different applications.
  • 该框架用于两个不同的应用程序。

  • For the first application, the dynamic cast works fine (returns b).
  • 对于第一个应用程序,动态转换工作正常(返回b)。

  • For the second application, the dynamic cast doesn't work (returns null).
  • 对于第二个应用程序,动态强制转换不起作用(返回null)。

  • For the second application, RTTI seems to be enabled because dynamic casts for other types work.
  • 对于第二个应用程序,似乎启用了RTTI,因为其他类型的动态强制转换工作。

So what could be causing the dynamic cast for this one type to fail in one application?

那么在一个应用程序中导致这种类型的动态转换失败的原因是什么?

2 个解决方案

#1


3  

Another thing that can happen with GCC is if some of your code is static-linked and some is dynamic-linked. Or if the same class is defined in two different dynamic libraries.

GCC可能发生的另一件事是,如果您的某些代码是静态链接的,而某些代码是动态链接的。或者,如果在两个不同的动态库中定义了相同的类。

For example, a type SomeClass in the static linked code will produce a SomeClass typeinfo. And the SomeClass in the dynamic linked code will also produce a SomeClass typeinfo.

例如,静态链接代码中的类型SomeClass将生成SomeClass typeinfo。并且动态链接代码中的SomeClass也将生成SomeClass typeinfo。

What I have seen is that most of the code will point to the dynamic SomeClass typeinfo while all of the code in the static-linked block will point to its internal copy of SomeClass typeinfo.

我所看到的是,大多数代码都指向动态SomeClass typeinfo,而静态链接块中的所有代码都将指向SomeClass typeinfo的内部副本。

Since GCC determines types for RTTI and exception handling via typeinfo pointers, this means that as far as it is concerned SomeClass and SomeClass are not the same type.

由于GCC通过typeinfo指针确定RTTI的类型和异常处理,这意味着就它而言,SomeClass和SomeClass的类型不同。

Now, Microsoft with Windows, probably because they deal with a lot more static linked code and old binary libraries that can't be recompiled, decided to do strcmp name comparisons of types which means that their RTTI and exception handling is a lot slower but works in almost all cases.

现在,微软与Windows,可能是因为他们处理了更多的静态链接代码和无法重新编译的旧二进制库,决定对类型进行strcmp名称比较,这意味着他们的RTTI和异常处理速度要慢很多但是有效在几乎所有情况下。

#2


1  

Had this happen to me once. The problem boiled down to the visibility of C++ symbols in the framework. Specifically, the symbols were hidden for some reason.

这曾经发生在我身上。问题归结为框架中C ++符号的可见性。具体而言,符号因某种原因被隐藏。

Now, dynamic_cast requires, in the derived class, to point to some type information for the base class, which can't happen if the symbol is not visible.

现在,dynamic_cast要求在派生类中指向基类的某些类型信息,如果符号不可见,则不会发生这种情况。

Bottom line, setting the visibility for the affected classes like that :

底线,为受影响的类设置可见性:

class __attribute__((visibility("default"))) SomeClass
{
    /* ... */
};

solved the issue for us

为我们解决了这个问题

#1


3  

Another thing that can happen with GCC is if some of your code is static-linked and some is dynamic-linked. Or if the same class is defined in two different dynamic libraries.

GCC可能发生的另一件事是,如果您的某些代码是静态链接的,而某些代码是动态链接的。或者,如果在两个不同的动态库中定义了相同的类。

For example, a type SomeClass in the static linked code will produce a SomeClass typeinfo. And the SomeClass in the dynamic linked code will also produce a SomeClass typeinfo.

例如,静态链接代码中的类型SomeClass将生成SomeClass typeinfo。并且动态链接代码中的SomeClass也将生成SomeClass typeinfo。

What I have seen is that most of the code will point to the dynamic SomeClass typeinfo while all of the code in the static-linked block will point to its internal copy of SomeClass typeinfo.

我所看到的是,大多数代码都指向动态SomeClass typeinfo,而静态链接块中的所有代码都将指向SomeClass typeinfo的内部副本。

Since GCC determines types for RTTI and exception handling via typeinfo pointers, this means that as far as it is concerned SomeClass and SomeClass are not the same type.

由于GCC通过typeinfo指针确定RTTI的类型和异常处理,这意味着就它而言,SomeClass和SomeClass的类型不同。

Now, Microsoft with Windows, probably because they deal with a lot more static linked code and old binary libraries that can't be recompiled, decided to do strcmp name comparisons of types which means that their RTTI and exception handling is a lot slower but works in almost all cases.

现在,微软与Windows,可能是因为他们处理了更多的静态链接代码和无法重新编译的旧二进制库,决定对类型进行strcmp名称比较,这意味着他们的RTTI和异常处理速度要慢很多但是有效在几乎所有情况下。

#2


1  

Had this happen to me once. The problem boiled down to the visibility of C++ symbols in the framework. Specifically, the symbols were hidden for some reason.

这曾经发生在我身上。问题归结为框架中C ++符号的可见性。具体而言,符号因某种原因被隐藏。

Now, dynamic_cast requires, in the derived class, to point to some type information for the base class, which can't happen if the symbol is not visible.

现在,dynamic_cast要求在派生类中指向基类的某些类型信息,如果符号不可见,则不会发生这种情况。

Bottom line, setting the visibility for the affected classes like that :

底线,为受影响的类设置可见性:

class __attribute__((visibility("default"))) SomeClass
{
    /* ... */
};

solved the issue for us

为我们解决了这个问题