|
i want to post a thread message that contain a CString variable like this:
<br />
PostThreadMessage(m_pThread->m_nThreadID,WM_MSG,0,(LPARAM)sString.GetBuffer(sString.GetLength()));<br />
and then handle the msg at the Thread side to process this CString variable
like this:
<br />
CString s = (LPTSTR)pMsg->lParam;<br />
AfxMessageBox(s);<br />
the code compile without errors but the data displayed in the Message box is not the same CString variable that have been sent
so i wanna know wat is wrong with this code
thnx 4 ur time and concern
|
|
|
|
|
singersinger wrote: PostThreadMessage(m_pThread->m_nThreadID,WM_MSG,0,(LPARAM)sString.GetBuffer(sString.GetLength()));
u pass a pointer to the function. Some times by the time the message was recieved by the thread, sString have got desctructed. So the memory that the lParam was pointing will b a invalid one.
Try the bolow approch.
LPTSTR lpMessage = new TCHAR[sString.GetLength()];
_tcscpy( lpMessage , sString);
PostThreadMessage(m_pThread->m_nThreadID,WM_MSG,0,(LPARAM)lpMessage);
and in the thread side
LPTSTR lpMessage = (LPTSTR)pMsg->lParam;;
CString s = lpMessage;
delete lpMessage;
AfxMessageBox(s);
nave
|
|
|
|
|
thnx alot 4 ur fast reply
this code solved the problem
thanks agian ;)
|
|
|
|
|
If you post a message, you can never be sure when in time the message will arrive on the other side. As such, you cannot use a CString object, unless you know for sure that will be alive when it arrives at the message's recipient. Consider this:
{
CString str = ...;
PostThreadMessage(m_pThread->m_nThreadID, WM_MSG, 0, LPARAM(str.GetBuffer());
}
LRESULT Handler(UINT nMsg, WPARAM wParam, LPARAM lParam)
{
LPCTSTR lpsz = LPCTSTR(lParam);
DoStuff(lpsz);
} Can you see the race condition? This will work, if and only if, the Handler() function gets to execute before the str goes out of scope (by which time it's destructor is called). Chances are (very likely) that the str object has been destroyed before Handler() is called. You passed a pointer to the internal string buffer inside the str object. That internal string buffer is deleted in the destructor of the str object. So, Handler() will receive a dangling pointer...
It is much safer if you do this:
{
CString str = ...;
TCHAR* copy = new TCHAR[str.GetLength() + 1];
lstrcpy(copy, str.GetBuffer()); str.ReleaseBuffer();
PostThreadMessage(m_pThread->m_nThreadID, WM_MSG, 0, LPARAM(copy));
}
LRESULT Handler(UINT nMsg, WPARAM wParam, LPARAM lParam)
{
LPTSTR lpsz = LPCTSTR(lParam);
DoStuff(lpsz);
delete [] lpsz;
} You allocate a copy of the string in the which you pass to the handler. It is then up to the handler to delete the string.
--
Mit viel Oktan und frei von Blei, eine Kraftstoff wie Benziiiiiiin!
|
|
|
|
|
Jörgen Sigvardsson wrote: lstrcpy(copy, str.GetBuffer()); str.ReleaseBuffer();
There is no need to call GetBuffer here. Just use the CString's implicit cast to LPCTSTR.
If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week
Zac
|
|
|
|
|
singersinger wrote: PostThreadMessage(m_pThread->m_nThreadID,WM_MSG,0,(LPARAM)sString.GetBuffer(sString.GetLength()));
I agree what Navin has said.
sString is destroyed by the time you tried to access it.
One more thing, GetBuffer call must accompanied by ReleaseBuffer to avoid memory leak.
|
|
|
|
|
prasad_som wrote: One more thing, GetBuffer call must accompanied by ReleaseBuffer to avoid memory leak.
No, that is not true. The CString object's methods are however not safe to use before a matching call to ReleaseBuffer().
--
Mit viel Oktan und frei von Blei, eine Kraftstoff wie Benziiiiiiin!
|
|
|
|
|
i have defined two class that you see below:
class Row
{
private:
char *termState;
int *terms;
public:
Row(int length,int mTCount);
};
class Table
{
private:
Row *rows;
public:
Table(int);
}
in Table() constructor i need to creat an array of Row objects dynamically like this :
Table::Table(int n)
{
rows = new Row[n];
}
how i can call the Row() constructor for this array? is this possible?
more information :
in Row() constructor i want to allocate memory for (char *termState) and
(int *terms) dynamically;
|
|
|
|
|
just a guess, why don't you use std::vector<> ?
|
|
|
|
|
i never used it.
can you give me a link for this topic?
|
|
|
|
|
MSDN : std::vector [^]
std::vector<CMyType> vec;
CMyType o1, o2;
vec.push_back(o1);
vec.push_back(o2);
std::vector<CMyType>::iterator iter;
for (iter = vec.begin(); iter != vec.end(); iter++) {
CMyType obj = *iter;
}
|
|
|
|
|
thanks toxcct
I'll try it
|
|
|
|
|
Alternatively, he could use the boost/tr1 array template as well.
If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week
Zac
|
|
|
|
|
erfi wrote: how i can call the Row() constructor for this array? is this possible?
It is possible to call the constructor of the row class. It get's invoked automatically on creation of an object.
ex: This code is not optimized. You should be using destructor of the classes to free the total amount of memory being allocated in this process.
#include "stdafx.h"
#include <iostream>
using namespace std;
class Row
{
private:
char *termState;
int *terms;
public:
Row(int length,int mTCount);
void Display();
};
Row::Row(int a,int b)
{
cout<<"Constructor of the row class is invoked"<<endl;
termState=new char[a];
terms=new int[b];
}
void Row::Display ()
{
cout<<"Display of row class";
}
class Table
{
private:
Row *rows[5];
public:
Table(int);
};
Table::Table(int a)
{
for ( int i=0;i<5;i++)
{
rows[i]=new Row (5,10);
rows[i]->Display();
}
}
int _tmain(int argc, _TCHAR* argv[])
{
Table t(10);
return 0;
}
Somethings seem HARD to do, until we know how to do them.
_AnShUmAn_
|
|
|
|
|
thank you _AnShUmAn_
but in your code you write this :
Row *rows[5];
but i need a parametric length for rows, like this:
Table::Table(int a)
{
rows = new Row[a];
}
when i compile this code this error appears :
"error C2512: 'Row' : no appropriate default constructor available"
i think that there is a better way:
i want to delete the Row() constructor and after creating the Row objects dynamically , allocate the memory for Row object's member with a member function of Row.
what do you think ? is this a good way?
|
|
|
|
|
I agree with toxcc - using vectors for stuff like this would be much easier, as they're especially designed to work just like arrays, but to be resizable at runtime
|
|
|
|
|
erfi wrote: "error C2512: 'Row' : no appropriate default constructor available"
try providing a default constructor in your class.
erfi wrote: allocate the memory for Row object's member with a member function of Row.
What's the problem with allocation of memory in the constructor itself.
Here's the code for you:
#include "stdafx.h"
#include <iostream>
using namespace std;
class Row
{
private:
char *termState;
int *terms;
public:
Row()
{
cout<<"In edefau"<<endl;
}
Row(int length,int mTCount);
void Display();
};
Row::Row(int a,int b)
{
cout<<"Constructor of the row class is invoked"<<endl;
termState=new char[a];
terms=new int[b];
}
void Row::Display ()
{
cout<<"Display of row class";
}
class Table
{
private:
Row *rows;
public:
Table(int);
};
Table::Table(int a)
{
rows=new Row [a];
rows->Display();
}
int _tmain(int argc, _TCHAR* argv[])
{
Table t(10);
return 0;
}
Try this out and let me know whether there exist some more problem..
-- modified at 9:42 Wednesday 20th September, 2006
Somethings seem HARD to do, until we know how to do them.
_AnShUmAn_
|
|
|
|
|
dude, stop trying to reinvent the wheel. the STL provides all this already, in a better way...
consider using vector
|
|
|
|
|
I want to copy a .ini file created using CStdioFile class, I want to copy the entire file to another similar .ini file. How shall I do this?
|
|
|
|
|
Sonia Horra wrote: want to copy the entire file to another similar .ini file
CopyFile()
Somethings seem HARD to do, until we know how to do them.
_AnShUmAn_
|
|
|
|
|
|
|
use win32 function copyFile() ; refer MSDN for complete documentation
|
|
|
|
|
Hi,
Can anyone please tell me, how to know whether an Event is already signalled or not.
I have an application(App01) which has an event, and checks if it is signalled using " WaitForSingleObject(mhEvent,0);"
Another Application(App02) signals App01, and it works in such a way that a switch is established and App01 just checks if this switch is on/off, and based on that it does all the processing required.
In App02 i am using OpenEvent(..) to get access to the Event created in App01. But before I call SetEvent() or ResetEvent(), I want to know whether the Event(in App01) is already signalled or not.
If it is already signalled, I would'nt need to call SetEvent() again.
this is same with the ResetEvenet().
App02 is a console app, and exits once Set/Reset is done on the App01 Event.
Any suggestions will be appreciated.
Thanks in Advance.
Thanks & Regards,
Dhana
|
|
|
|
|
I do not know of such a function. Try using a Semaphore instead. Initialize it whith a value of 1. Whenever an instance of App2 wants to Signal App1, it decreases the Semaphore by one and then signals to App1 using the Event. App1 then checks the Semaphore. If it is 0, then it does all its calculation, resets the even (better would be an auto-reset event), and then increases the semaphore again. This way, you automatically implement a queue for all instances of App2, that want to signal App1. No signal is lost. Of course, i do not know if that was what you intended.
If you wanted to check because of performance issues, you can neglect that. Conditional execution creates performanceoverhead itself, and a vain call to SetEvent() will not matter. In any case App2 should not be the one to reset the Event. App1 should always do that, to indicate that it is waiting.
Hope that helped a little.
|
|
|
|