1

以下のような単純なクラスがあるとします。

class Foo
{
public:
    Foo(){};
protected:
    int meth1( void ){return 0;};
public:
    int var1;
};

MSVC でコンパイルし、DbgHelp API を介して対応する PDB を解析すると、子を反復処理してメソッドと変数をうまく解析できますが、特定の子のアクセス指定子を決定する方法がわかりません。私のコードは次のようになります。

// The symbol tag for 'index' is a SymTagEnum::SymTagBaseClass

DWORD item_count;
if( !::SymGetTypeInfo( process, base_address, index, TI_GET_CHILDRENCOUNT, &item_count ) )
    break;

if( item_count > 0 )
{
    TI_FINDCHILDREN_PARAMS * item_indexs = new TI_FINDCHILDREN_PARAMS[item_count];

    item_indexs->Count = item_count;
    item_indexs->Start = 0;

    if( ::SymGetTypeInfo( process, base_address, index, TI_FINDCHILDREN, item_indexs ) )
    {
        for( DWORD i=0 ; i<item_count ; i++ )
        {
            DWORD item_tag;
            if( !::SymGetTypeInfo( process, base_address, item_indexs->ChildId[i], TI_GET_SYMTAG, &item_tag ) )
                break;

            DWORD item_type_index;
            if( !::SymGetTypeInfo( process, base_address, item_indexs->ChildId[i], TI_GET_TYPEID, &item_type_index ) )
                break;

            // XXX: How to discover the access specifier (public, private, protected) for
            // the class method/variable at 'item_type_index'?

            switch( item_tag )
            {
                case SymTagEnum::SymTagFunction:
                {
                    // parse out the class method at 'item_type_index'
                    break;
                }
                case SymTagEnum::SymTagData:
                {
                    // parse out the class variable at 'item_type_index'
                    break;
                }
                default:
                {
                    break;
                }
            }
        }
    }
}

DbgHelp API を介してクラスの子のアクセス指定子 (public、private、protected) を決定することは可能ですか?

4

1 に答える 1

1

はい、技術的に可能です。関数の装飾された (マングル化された) 名前を取得します。あなたの場合、それは?meth1@Foo@@IAEHXZ. 装飾された C++ 名は、常に疑問符で始まります。これをUnDecorateSymbolName() 関数にフィードして、C++ 識別子名に戻すことができます。どっちが:

protected: int __thiscall Foo::meth1(void)

アクセス指定子がどのように含まれているかに注意してください。

于 2013-11-06T19:21:36.017 に答える