c ++指针转换帮助,void *到布尔值

时间:2013-03-03 08:52:33

标签: c++ pointers plugins casting

我现在正在学习C ++,并且在使用指针时遇到了一些问题。首先,我不确定我想要做的是我想要做的事情。

我正在尝试使用一个函数,该函数可以根据字符串参数返回指向各种方法指针的相应指针,然后使用方法指针。

#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
using namespace std;

typedef void* (*plugin_function)(void*);

static class Plugin
{
public:
    static bool doBoolStuff(){
        return true;// A Simple function that returns true
    }
};

void* getFunction(string pluginName, string functionName)
{
    if(pluginName =="Bool"){
        return &Plugin::doBoolStuff;
            //If the string is right it should return a method pointer.
            //I think that void* has the ability to point to anything, I am trying
            //to use that functionality to create a system where I am able to set 
            //some parameters and get the appropriate method pointer.
    }else{
        return NULL;
    }
}

int main(int argc, _TCHAR* argv[])
{
    void* pluginFunction;
    pluginFunction = getFunction("Bool","");

    if(pluginFunction == &Plugin::doBoolStuff)cout<<"CastSuccesful!"<<endl;

    //This section right here is where my code is breaking.
    //
    // IntelliSense: expression preceding parentheses of apparent call must have              
    //(pointer-to-) function type   
    //c:\Users\Walter\Dropbox\Inscription\MethodCasting\MethodCasting\MethodCasting.cpp 
    //MethodCasting

    cout << "Bool function ->"<< pluginFunction()<<endl;
    cout << "--------------------------------"<<endl;
    system("pause");

}

任何反馈都会有所帮助。

3 个答案:

答案 0 :(得分:2)

编辑:不对,抱歉。正如@Stephen Lin指出的那样,我没有阅读static修饰符......所以虽然你想要的东西不适用于非静态成员函数,但它通常适用于使用reinterpret_cast的静态成员(此行为是实现定义的):

class Plugin {
    public:
    static bool foo()
    {
        std::cout << "Foo called!" << std::endl;
        return true;
    }
};

void *get_func()
{
    return reinterpret_cast<void *>(&Plugin::foo);
}

int main()
{
    void *pluginFunction = get_func();
    (reinterpret_cast<bool (*)()>(pluginFunction))();
    return 0;
}

原帖:


你做不到。根据{{​​3}}:

  

但是,没有办法将void *强制转换回您实际可以使用的成员函数指针。

我自己尝试过。实际上,所有static_castreinterpret_cast甚至旧的C风格演员都拒绝合作 - 无论是void *,还是bool (*)()(是的,我甚至试过从非成员函数指针类型转换为成员函数类型)...

很抱歉,C ++似乎不允许我们这样做。

答案 1 :(得分:0)

一些修改,但我们应该尽量减少铸件,但一种可能性是:

plugin_function getFunction(string pluginName, string functionName)
{
    if (pluginName == "Bool")
    {
        return (plugin_function)Plugin::doBoolStuff;

int main(int argc, _TCHAR* argv[])
{
    typedef bool (*Func)();
    Func pluginFunction = (Func)getFunction("Bool", "");

输出

  

CastSuccesful!

     

布尔函数 - &gt; 1

答案 2 :(得分:0)

这取决于您的实施,如果您可以这样做。在便携式C ++中你不能。即使你可以,你需要显式的强制转换(在这种情况下为reinterpret_cast<>)来转换不同的指针类型。

请注意,这不会扩展到真正的“方法”指针,即非静态成员函数指针。您不能在成员函数指针和对象指针或普通函数指针之间进行转换。如果具有非静态成员函数指针,则可以使用我最后提供的方法。

Portably reinterpret_cast<>可以在函数指针类型和对象指针类型之间自由转换 - 尽管在几乎所有情况下都不会使用除转换回原始类型之外的结果。

对于对象指针类型和函数指针类型之间的转换,C ++ 11标准说(§5.2.10[expr.reinterpret.cast] / 8):

  

将函数指针转换为对象指针类型,反之亦然   有条件支持。这种转换的意义是   实现定义,但实现支持   双向转换,将一种类型的prvalue转换为   另一种类型和背面,可能具有不同的cv-资格,   将产生原始指针值。

因此,它取决于您的实现(并且应该记录在其文档中),如果将一个函数指针转换为void *编译并返回编译。唉,如果确实如此,你应该得到预期的行为。

在您的代码中,丢失了强制转换。您需要在void*中对通用类型(在您的情况下为getFunction)进行强制转换,并且需要转换回原始类型才能调用该函数。因此,您需要知道main()中的原始类型:

void* pluginFunction = getFunction("Bool","");
// ....
cout << "Bool function ->"<< (reinterpret_cast<bool (*)()>(pluginFunction))()<<endl;

更便携的解决方案是使用任意函数指针类型,例如void (*)()来传递插件函数指针,以便你有:

typedef void (*any_func_ptr)();

// If you wanted to use this for non-static member functions, you could do
//   struct AnyClass;
//   typedef void (AnyClass::*any_memfun_ptr)();

any_func_ptr getFunction(string pluginName, string functionName)
{
    if(pluginName =="Bool"){
        return reinterpret_cast<any_func_ptr>(&Plugin::doBoolStuff);
    }else{
        return NULL;
    }
}

int main(int argc, char* argv[])
{
    any_func_ptr pluginFunction = getFunction("Bool","");

    if(reinterpret_cast<bool (*)()>(pluginFunction) == 
         &Plugin::doBoolStuff)
             cout<<"CastSuccesful!"<<endl;

    cout << "Bool function ->"<< (reinterpret_cast<bool (*)()>(pluginFunction))()<<endl;

}