使用static_cast检查void * to Object是否成功

时间:2018-04-14 11:20:30

标签: c++ pointers casting void-pointers

我正在开发一个将从C#调用的C ++插件。我尝试移植的API带有数百个函数,其中大多数只是具有相同名称但具有不同数据类型的重载,如intfloatchar

我不是一遍又一遍地在C ++和C#端编写相同的代码但是使用不同的数据类型,而是想使用通用指针对它进行一次函数重载。我的目标是使用static_cast中的void*intfloat然后char并使用哪个首先成功。

来自C ++方面的简单测试函数:

void calculate(void* input1, void* input2)
{
    float *i1 = static_cast<float*>(input1);
    if(i1==NULL)
    std::cout<<"Bad"<<std::endl;
    else
    std::cout<<*i1<<std::endl;
}

int main()
{
   int input1 = 5;
   int input2 = 10;

   calculate(&input1,&input2);

   return 0;
}

这应该输出“BAD”,但似乎显示“7.00649e-45”,我认为这是一种未定义的行为。 static_cast失败了,我不知道如何检查它是否成功。在这种情况下,检查NULL是否有用。

是否可以检查void*对象static_cast是否成功?如果是这样,怎么样?

注意

这不是this问题的重复。我不想从void*找出对象的类型。我只想检查转换或static_cast是否成功。就是这样。

2 个答案:

答案 0 :(得分:1)

使用static_cast来恢复函数参数的类型是不合适的,因为转换将在编译时从void*float*完成。由于存在这种类型的转换链,编译器不会抱怨并且在执行期间,转换本身不会失败,即使它不能保证结果。

同样适用于在调用calculate函数时从int*void*的转换。

对于这种情况,您可以考虑使用模板函数来利用C ++的元编程功能。

这是一个剪辑开头:

template <class T*>
void calculate(T* a, T* b) {
    // your implementation here
}

编辑

如果你只需要为一些类型导出模板函数,比如int,float,double等,你可以考虑在你的库的一个cpp文件中为每个类型添加一个模板专门化,其中包括模板功能已声明。

以下是int*类型的示例。

   template __declspec(dllexport) calculate<int*>(int* a, int* b);

答案 1 :(得分:0)

static_cast不执行类型检查,不能用于可靠地检索类型。此外,传递给您的函数的是void*指针,此时类型信息将丢失,甚至dynamic_cast都不会有帮助。因此,即使在纯C ++中,如果没有模板,这也是一个难以解决的问题。 void*指针实际上是C#System.IntPtr这一事实使问题复杂化,据我所知,没有足够强大的互操作层来检索原始类型(即使是原始类型)。

像这样的问题是为什么像cog这样的样板代码生成器被发明了。有很多他们在那里,你可能想做一些研究,找到最适合你的需求。 Cog的工作原理是插入嵌入在C ++(或C#或其他)文件中的代码生成脚本,并将其注入到构建过程中。您可能会发现(相对较小的)时间投资(与手动生成样板代码相比)值得。