1

expatを使用してxmlファイルを読み取ります。xmlファイルで指定された構成からクラスメンバー変数の一部を設定したいと思います。startelementハンドラーを定義しました。

void Start(void *data,const XML_Char *el, const XML_Char **attr)

これは次のように参照されます。

XML_SetElementHandler(parser,Start, NULL);

現在、私はグローバル構造を使用して、g_stConfigInfoすべての値をに格納していますStart()

例えば、

void Start(void *data,const XML_Char *el, const XML_Char **attr)
{
    if( _tcscmp(el,_T("blah"))==0 )
    {
        for (int i=0; attr[i]; i+=2)
        {
            if(_tcscmp(attr[i],_T("name"))==0)
            {
                g_stConfigInfo.sInputName = attr[i+1];
            }
            .........

それから私はやっていますmyclass.sInputName = g_stConfigInfo.sInputname

グローバル変数を使用せず、代わりに、メンバー変数を設定する必要があるクラスのメンバー関数にすることができます。Start()内にもこのクラスのインスタンスを入れたくありません。これを行うための最良の方法は何ですか?

4

2 に答える 2

1

私はこれまでExpatを使用したことがありませんが、XML_SetUserDataを使用することが望ましいと思います。

class my_data
{
    public:
    static void start_callback(void *data, const XML_Char *el, const XML_Char **attr)
    {
        static_cast<my_data*>(data)->start(el, attr);
    }

    void start(const XML_Char *el, const XML_Char **attr);
};

//...
my_data data;
XML_SetUserData(parser, &data);
XML_SetElementHandler(parser, my_data::start_callback, NULL);

SetUserDataにより、パーサーは、指定したポインターをハンドラーコールバックに渡します。 http://www.xml.com/pub/a/1999/09/expat/index.html?page=3#setuserdata

于 2010-09-23T14:04:49.830 に答える
1

クラス メンバー関数は、暗黙的なデータ コンテキストが付加された通常の関数と同じです。したがって、グローバル データの参照を避けたい場合は、何らかの方法で NULL 以外のコンテキスト引数を に渡す必要がありますStart

それを行う慣用的な方法は、通常、次のようになります。

class MyHandler {
public:
    void Start(const XML_Char *el, const XML_Char **attr) {
        // ...dispatch on "el" here.
        // e.g. a map of strings to member function pointers
    }
};
...

template<T>
void
Start(void *data, const XML_Char *el, const XML_Char **attr)
{
    T *handler = static_cast<T*>(data);
    handler->Start(el, attr);
}

MyHandler handler;
XML_SetUserData(parser, handler);
XML_SetElementHandler(parser, Start<MyHandler>, NULL);

つまり、クラスが何らかの XML 要素に対応している場合、それをハンドラー関数に渡すことは間違いではありません。

于 2010-09-23T13:42:32.817 に答える