Question

The code below is mine structure and class containing the structure reference.

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

When i compile the above code i am getting the following errors in DeleteMessageQueue function

error C2451: conditional expression of type '_bstr_t' is illegal error C2228: left of '.Detach' must have class/struct/union

Was it helpful?

Solution

A couple of things, first the meat of your error

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

Message::Name is a raw BSTR pointer, which I assure you does not have a member function called Detach(). The _bstr_t class, however, does. Change your struct to:

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

Once done, you can remove the SysFreeString() call entirely, since now both Name and TimeStampIs are smart pointers and will auto-free on object destruction.

OTHER TIPS

Like this

SysFreeString(pMess->Name);

But there is no good reason to use BSTR in code like this. Nor is there any good reason to be writing your own linked list class. Do it the easy way (as selbie pointed out this isn't the only error in your code), I would recommend std::wstring and std::list.

#include <string>
#include <list>

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

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

The big advantage is then you don't have to delete anything. So all those issues go away.

Change this line:

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

To this:

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

But that's not your only problem...

Also, this line is flat out wrong:

Message->Name=L"ABC";

You are assigning a WCHAR* to a BSTR. Which for all intents and purposes will work just fine until the moment you release it via SysFreeString. (Which could crash.)

Allocate your string as follows:

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

The _bstr_t is a useful string class that internally holds a BSTR. It takes care of all the SysAllocString/SysFreeString calls for you when converting to/from native WCHAR* strings. So it would make sense to use it for Name just like you use it for TimeStampIs.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top