2

現在 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");

}

どんなフィードバックも役に立ちます。

4

2 に答える 2

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;
}

元の投稿:


できません。この記事によると:

void *ただし、実際に使用できるメンバー関数ポインターにバックをキャストする方法はありません。

私はそれを自分で試しました。実際には、すべてのstatic_cast、および古い C スタイルのキャストでさえ、reinterpret_cast動作を拒否しました。void *bool (*)()

申し訳ありませんが、C++ ではこれができないようです。

于 2013-03-03T09:06:50.860 に答える
0

これができるかどうかは、実装に依存します。移植可能な C++ ではできません。reinterpret_cast<>また、できたとしても、異なるポインター型間で変換するには、明示的なキャスト (この場合は ) が必要です。

これは、実際の「メソッド」ポインター、つまり非静的メンバー関数ポインターには拡張されないことに注意してください。メンバー関数ポインターと、オブジェクト ポインターまたは通常の関数ポインターとの間で変換することはできません。非静的メンバー関数ポインター しかない場合は、最後に提示するアプローチを使用できます。

Portablyreinterpret_cast<>は、関数ポインター型とオブジェクト ポインター型の間で自由に変換できますが、元の型への変換以外の結果の使用は、ほとんどの場合未定義です。

オブジェクト ポインター型と関数ポインター型の間の変換について、C++11 標準は次のように述べています (§5.2.10 [expr.reinterpret.cast]/8)。

関数ポインターからオブジェクト ポインター型への変換、またはその逆の変換は、条件付きでサポートされています。このような変換の意味は実装によって定義されますが、実装が両方向の変換をサポートしている場合を除いて、ある型の prvalue を別の型に変換したり、元の型の 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;

}
于 2013-03-03T11:48:52.933 に答える