简体   繁体   English

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

[英]Check if void* to Object with static_cast is successful

I am working on a C++ plugin that will be called from C#. 我正在开发一个将从C#调用的C ++插件。 The API I am trying to port comes with hundreds of functions and most of them are just overloads with the-same name but with different datatypes like int , float and char . 我试图移植的API带有数百个函数,其中大多数只是具有相同名称但具有不同数据类型(如intfloatchar重载。

Instead of writing the-same code but with different datatypes on both C++ and C# side over and over again, I want to use one function overload for it with a generic pointer. 我不是一遍又一遍地在C ++和C#端编写相同的代码但是使用不同的数据类型,而是希望使用通用指针对它进行一次函数重载。 My goal is to use static_cast from void* to int , float and then char and use which one that is successful first. 我的目标是使用static_castvoid*intfloat然后char和使用哪一个是第一个成功。

A simple test function from the C++ side: 一个来自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;
}

This is supposed to output "BAD" but it seems to be showing "7.00649e-45" which I believe is an undefined behavior. 这应该输出“BAD”,但似乎显示“7.00649e-45”,我认为这是一种未定义的行为。 The static_cast is failing and I don't know how check if it is successful or not. static_cast失败了,我不知道如何检查它是否成功。 Checking if it is NULL did not help in this case. 在这种情况下,检查它是否为NULL没有帮助。

Is it possible to check if void* to Object with static_cast is successful or not? 是否可以通过static_cast检查对象的void*是否成功? If so, how? 如果是这样,怎么样?

Note : 注意

This is not a duplicate of this question. 这不是这个问题的重复。 I don't want to find out the type of the Object from void* . 我不想从void*找出Object的类型。 I just want check if the conversion or static_cast is successful or not. 我只想检查转换或static_cast是否成功。 That's it. 而已。

The use of static_cast to recover the type of the argument of your function is not appropriate because the casting will be done at compile time from void* to float* . 使用static_cast来恢复函数参数的类型是不合适的,因为转换将在编译时从void*float* Since a conversion chain for this types exists, the compiler will not complain and during execution, the casting itself will not fail, even if there is no guarantee on the result of it. 由于存在这种类型的转换链,编译器不会抱怨并且在执行期间,即使不能保证其结果,转换本身也不会失败。

The same applies to the casting from int* to void* when invoking the calculate function. 这同样适用于在调用calculate函数时从int*void*的转换。

Maybe for this case you could consider the use of a template function to exploit the metaprogramming feature of C++. 也许对于这种情况,您可以考虑使用模板函数来利用C ++的元编程功能。

Here is a snipped to start with: 这是一个剪辑开始:

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

EDIT 编辑

If you need to export the template function only for a few types, like int, float, double etc you may consider adding this a template specialization for each type in one of the cpp files of your library that includes the header where the template funcion is declared. 如果你需要只为几种类型导出模板函数,比如int,float,double等,你可以考虑在你的库的一个cpp文件中为每个类型添加一个模板专门化,其中包含模板功能所在的头部。声明。

Here is an example for the int* type. 这是int*类型的示例。

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

static_cast performs no type checking and cannot be used to reliably retrieve the type. static_cast执行类型检查,不能用于可靠地检索类型。 Furthermore, what is passed into your function is a void* pointer, at which point type information is lost and not even dynamic_cast would help. 此外,传递给您的函数的是void*指针,此时类型信息将丢失,甚至dynamic_cast也不会有帮助。 So this would be a hard problem to solve without templates even in pure C++. 因此,即使在纯C ++中,如果没有模板,这也是一个难以解决的问题。 The fact that the void* pointer is actually a C# System.IntPtr compounds the problem and to the best of my knowledge there is no interop layer powerful enough to retrieve the original type (even if primitive). void*指针实际上是C# System.IntPtr这一事实使问题复杂化,据我所知,没有足够强大的互操作层来检索原始类型(即使是原始类型)。

Problems like this one is why boilerplate code generators like cog were invented. 像这样的问题是为什么像cog这样的样板代码生成器被发明了。 There are a bunch of them out there and you may want to do some research to find which one best fits your needs. 有很多他们在那里,你可能想做一些研究,找到最适合你的需求。 Cog works by inserting code generation scripts embedded right in C++ (or C#, or whatever) files and can be injected into your build process. Cog的工作原理是插入嵌入在C ++(或C#或其他)文件中的代码生成脚本,并将其注入到构建过程中。 You may find it worth the (relatively small) time investment (compared to generating the boilerplate code manually). 您可能会发现(相对较小的)时间投资(与手动生成样板代码相比)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM