0

以下のコードは、鉱山の構造と構造参照を含むクラスです。

typedef struct MESSAGE
{
    int MessageType;
     BSTR Name;
    _bstr_t TimeStampIs;
} MESSAGE, *PMESSAGE;

typedef struct MESSAGENODE
{
    PMESSAGE Message;
    MESSAGENODE* pNext;
} MESSAGENODE, *PMESSAGENODE;


class Message
{
private:
    PMESSAGENODE        MessageQueueFront;
    PMESSAGENODE        MessageQueueBack;
public:
    bool AddMessageToQueue(PMESSAGE Message);
    void DeleteMessageQueue(void){
    PMESSAGE pMess;
    while((pMess = GetMachineMessage()) != NULL)
    {
        if((pMess->DialysisDataIs))
        SysFreeString(pMess->Name.Detach());
        delete pMess;
}
}m;

int main()
{
PMESSAGE Message;
    Message = new MESSAGE;
    Message->Name=L"ABC";
    Message->TimeStampIs=L"25252";
    m.AddMessageToQueue(Message);
    m.DeleteMessageQueue();
    return 0;
}

上記のコードをコンパイルすると、DeleteMessageQueue関数で次のエラーが発生します

エラーC2451:タイプ'_bstr_t'の条件式は不正ですエラーC2228:'.Detach'の左側にはクラス/構造体/共用体が必要です

4

3 に答える 3

3

いくつかのこと、最初にあなたのエラーの本質

SysFreeString(pMess->Name.Detach());

Message::Nameは生のBSTRポインターであり、。というメンバー関数がないことを保証しますDetach()。ただし、_bstr_tクラスはそうします。構造体を次のように変更します。

typedef struct MESSAGE
{
    int MessageType;
    _bstr_t Name;
    _bstr_t TimeStampIs;
} MESSAGE, *PMESSAGE;

完了したら、SysFreeString()NameとTimeStampIの両方がスマートポインターであり、オブジェクトの破棄時に自動的に解放されるため、呼び出しを完全に削除できます。

于 2012-11-02T07:44:44.900 に答える
2

このような

SysFreeString(pMess->Name);

しかし、このようなコードでBSTRを使用する正当な理由はありません。また、独自のリンクリストクラスを作成する正当な理由もありません。簡単な方法で実行してください(セルビーが指摘したように、これがコードのエラーだけではありません)、私はお勧めstd::wstringstd::listます。

#include <string>
#include <list>

struct MESSAGE
{
    int MessageType;
    std::wstring Name;
    std::wstring TimeStampIs;
};

class Message
{
private:
    std::list<MESSAGE> queue;
public:
    ...
};

大きな利点は、何もする必要がないことですdelete。したがって、これらの問題はすべて解消されます。

于 2012-11-02T07:45:52.790 に答える
0

この行を変更します。

SysFreeString(pMess->Name.Detach());

これに:

SysFreeString(pMess->Name);
pMess->Name = NULL;

しかし、それだけが問題ではありません...

また、この線は完全に間違っています:

Message->Name=L"ABC";

WCHAR*をBSTRに割り当てています。これは、SysFreeStringを介してリリースするまで、すべての目的と目的で問題なく機能します。(クラッシュする可能性があります。)

次のように文字列を割り当てます。

pMess->Name = SysAllocString("ABC");

_bstr_tは、BSTRを内部的に保持する便利な文字列クラスです。ネイティブのWCHAR*文字列との間で変換するときに、すべてのSysAllocString/SysFreeString呼び出しを処理します。したがって、TimeStampIsに使用するのと同じように、Nameにも使用するのが理にかなっています。

于 2012-11-02T07:45:19.487 に答える