Click here to Skip to main content
16,017,833 members
Please Sign up or sign in to vote.
4.67/5 (15 votes)
See more:
I would appreciate it if someone can provide me with a code sample for using CAtlArray as a member variable inside a class, where the array should hold a custom data structure.

I have defined the data structure:
C++
typedef struct
{
	int Status;
	CTime StatusDate;
} MyDataStructure;


Then, in my class, I define:

C++
private:
	CAtlArray<MyDataStructure> MyArray;


When I call RemoveAll(), or try to add a new item, I get an Access Violation error.
I tried to use SetCount() prior to adding members, but it didn't work as well.
Posted
Comments
cariolihome 6-Oct-12 19:18pm    
Please, show Your code

May be you have missed to malloc first before insert into MyArray.
C++
MyDataStructure* pNewStruct;
pNewStruct =(MyDataStructure* )malloc(sizeof(MyDataStructure));
MyArray.Add(pNewStruct);

Hope this will work.
 
Share this answer
 
This work for me and i get value after thread exit. Compare your code with me , you can understand your problem. Another thing CreateThread can not call a member function, so you must need a static function for this.,

C++
#include "stdafx.h"
#include <atlbase.h>
#include <atltime.h>
#include <atlcoll.h>
#include <atldebugapi.h>
 
class MyClass
{
public:
	typedef struct
	{
		CString* FullPath;
		CTime* StatusDate;
		MyClass* pClass;
	} _Item;

	MyClass();
	~MyClass();
	void StartThread();
	void* MyThread(void* arg);
	typedef _Item Item;
	Item MyItem;

	static void _MyThread(void* lpParam)
	{
		Item* obj = (Item* )lpParam;
		
		MyClass* a = obj->pClass;
		a->MyThread(lpParam);
	}
//private:
	CAtlArray<item*> MyArray;
};


MyClass::MyClass()
{
}
void MyClass::StartThread()
{
	HANDLE handle;
	int val=0;
	Item* MyNewItem = (Item* )malloc(sizeof(Item));
	//wcscpy(MyNewItem.FullPath.GetBuffer(),L"c:\\");
	MyNewItem->FullPath = new CString(L"c:\\");
	MyNewItem->pClass = this;
	handle = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)&_MyThread, MyNewItem, 0, NULL);  
	if ( handle == NULL)  ExitProcess(0);
 
}
void* MyClass::MyThread(void* arg)
{
	Item* newObj = (Item* )arg; 
	MyArray.Add(newObj);
	return 0;
}
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow)
{
	MyClass *myClass = new MyClass();
	myClass->StartThread();
	Sleep(200);  
	CString str;
	str.Format(L"\n\n--- PATH=%s --- \n\n",*(myClass->MyArray.GetAt(0)->FullPath));
	OutputDebugString(str);

	return 1;
}
</atldebugapi.h></atlcoll.h></atltime.h></atlbase.h>


Best of luck :D
 
Share this answer
 
How can I get notified, to the main even loop when this thread completes?
 
Share this answer
 
Something like

C++
// testproject.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <atlbase.h>
#include <atltime.h>
#include <atlcoll.h>
typedef struct
{
	CString FullPath;
	CTime StatusDate;
} Item;

class MyClass
{
public:
	MyClass();
	~MyClass();
	void StartThread();
	void* MyThread(void* arg);
	Item MyItem;
private:
	CAtlArray<item> *MyArray;
};

void MyClass::StartThread(void)
{
	HANDLE handle;
	int val=0;
	Item MyNewItem;
	wcscpy(MyNewItem.FullPath.GetBuffer(),L"c:\\");
	
	handle = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE) &MyClass::MyThread, &MyNewItem, 0, NULL);  
    if ( handle == NULL)  ExitProcess(0);

}
void* MyClass::MyThread(void* arg)
{
	Item* newObj = (Item* )arg; 
	MyArray->Add(*Item);
	
	return TRUE;
}
int _tmain(int argc, _TCHAR* argv[])
{
	MyClass *myClass = new MyClass;
	myClass->StartThread();
	return 1;
}




</item></atlcoll.h></atltime.h></atlbase.h>
 
Share this answer
 
[ bappycse05] is correct but I also used a Thread which is a member function of a class and wanted it to access the class's member variables, but the moment the thread ends, any changes it makes in any member variables are erased.
 
Share this answer
 
v2
It will be better if you post a little bit of code. However,
suppose classname is MyClass and your thread name MyThread. You call this thread from your class.
then try this..

C++
_beginthread(MyThread,0,this);

void* MyThread(void* arg)
{
   MyClass* newObj = (MyClass* )arg; 
  // now you can use all variable or method of this class using this object;
  newObj->MyArray.add(YourStructure); 
}


if this will not work for you then please post some code.

Well, try this code:

C++
// testproject.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <atlbase.h>
#include <atltime.h>
#include <atlcoll.h>
typedef struct
{
	CString FullPath;
	CTime StatusDate;
} Item;
 
class MyClass
{
public:
	MyClass();
	~MyClass();
	void StartThread();
	void* MyThread(void* arg);
	Item MyItem;
private:
	CAtlArray<item> *MyArray;
};
 
void MyClass::StartThread(void)
{
	HANDLE handle;
	int val=0;
	Item MyNewItem;
	wcscpy(MyNewItem.FullPath.GetBuffer(),L"c:\\");
	
	handle = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE) &MyClass::MyThread, &MyNewItem, 0, NULL);  
    if ( handle == NULL)  ExitProcess(0);
 
}
void* MyClass::MyThread(void* arg)
{
	Item* newObj = (Item* )arg; 
	MyArray->Add(*Item);
	
	return TRUE;
}
int _tmain(int argc, _TCHAR* argv[])
{
	MyClass *myClass = new MyClass;
	myClass->StartThread();
	return 1;
}
 
Share this answer
 
v2
Comments
Michael Haephrati 20-Oct-12 13:56pm    
It looks to me as if any change you make inside the thread doesn't affect the data structure after the thread has ended, so MyArray is not updated. Why don't you check and see.
Use this ---
dwRet = WaitForSingleObject(HANDLE,TIME);

see the example ..
http://www.installsetupconfig.com/win32programming/threadprocesssynchronizationapis11_13.html[^]

when thread will be completed, use postmessage method to inform UI :D
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900