PDA

View Full Version : Passing a pointer in Signal/Slot Connection



mclark
6th November 2007, 16:53
Greetings,

I am trying to pass a pointer as a parameter using signal/slot connections. I am having problems accessing the data on the slot side. On the 2nd or 3rd access the app crashes.

I have a number of other successful connections between these 2 classes already but none attempt to pass a pointer as a parameter. It would seem to be a simple thing to pass a void*. Is there a particular way to pass a void* using signal/slot connections?

Does anyone see what I am doing wrong?

Using Qt 4.2.2 and MSVC 2005.

Here are some code snippets...


// GetProperty Map
typedef struct deviceData
{
uint nCounter; // property counter
void* pData; // device data pointer

} DevData;

typedef std::map<unsigned long, DevData*> GetPropertyMap;
typedef GetPropertyMap::iterator GetPropertyMapIter;
typedef GetPropertyMap::value_type GetPropertyEntry;

GetPropertyMap m_PropMap;

// Signal declaration
void allDMXPropsReceived( unsigned long member, void* pData );


// Create structure
DevData* pDevData = new DevData();
pDevData->nCounter = nPropTotal;
pDevData->pData = static_cast<void*>( pNode );

m_PropMap.insert( GetPropertyEntry( handle, pDevData ) );
.
.
.
// Retreive the data pointer from the struct in the map
GetPropertyMapIter mit = m_PropMap.find( member );
if ( mit != m_PropMap.end() )
{
if ( mit->second != NULL )
{
...
if ( mit->second->pData != NULL )
emit allDMXPropsReceived( member, mit->second->pData );
...
}
}


//Slot declaration
void SLOT_AllDMXPropsReceived( unsigned long u4member, void* pData );

// Slot connection
connect( m_pController, SIGNAL( allDMXPropsReceived( unsigned long, void* ) ),
this, SLOT( SLOT_AllDMXPropsReceived( unsigned long, void* ) ), Qt::QueuedConnection );


void DMXTable::SLOT_AllDMXPropsReceived( unsigned long u4member, void* pData )
{
CDMXGateway* pNode = static_cast<CDMXGateway*>( pData );

// Access data & crash
SetDeviceName( pNode->GetDeviceName() );
SetIPAddr( pNode->GetIPAddr() );
...

momesana
6th November 2007, 18:22
maybe you should try dynamic_cast<> and only access the data if the pointer to the casted object is valid. At least, that is the safest way to do a cast.



void DMXTable::SLOT_AllDMXPropsReceived( unsigned long u4member, void* pData )
{
CDMXGateway* pNode = dynamic_cast<CDMXGateway*>( pData );
if (pNode) {
// Access data & crash
SetDeviceName( pNode->GetDeviceName() );
SetIPAddr( pNode->GetIPAddr() );
...
}

marcel
6th November 2007, 18:26
maybe you should try dynamic_cast<> and only access the data if the pointer to the casted object is valid. At least, that is the safest way to do a cast.



void DMXTable::SLOT_AllDMXPropsReceived( unsigned long u4member, void* pData )
{
CDMXGateway* pNode = dynamic_cast<CDMXGateway*>( pData );
if (pNode) {
// Access data & crash
SetDeviceName( pNode->GetDeviceName() );
SetIPAddr( pNode->GetIPAddr() );
...
}

Are you advising him to patch his code?

@mclark: Could we see the code from the thread where you emit the signal?
BTW, you shouldn't use void*, but register your custom type with qRegisterMetaType.
And if you're using visual studio, why in the world won't you debug the application? You can't get a debugger better than that.

mclark
6th November 2007, 18:36
Thank you for taking the time to look at my code.

It turns out this is not a Qt issue after all. But, of course, as soon as I post to the forum, the real problem hits me in the face. The pointer is coming across just fine when passing as a void*. The data is accessible in the slot as I expect. All would work if this programmer would not delete the data and then try to use it. :o

Again, thanks for your time.

momesana
6th November 2007, 20:04
Are you advising him to patch his code?
I thought the crash may have been the result of a pointer pointing to the wrong object (not having the members he tried to call.) or a dangling pointer. In both cases the dynamic_cast would have returned a null pointer. Thus he could have avoided the crashes. But in his case, the object was deleted from outside while he tried to access it, so it wouldn't have helped him to use a dynamic_cast.