Not sure what is wrong with parameter 3 or the setup?
error C2440: 'type cast' : cannot convert from '' to 'unsigned long (__stdcall *)(void *)'
None of the functions with this name in scope match the target type
--
void CNumbergeneratorDlg::OnBtn3()
{
//CreateThread
hThread1 = CreateThread(NULL, 0, Thread1, this, 0, NULL);//<--is "this" correct
WaitForSingleObject(hThread1,INFINITE);
TerminateThread(hThread1,0);
CloseHandle(hThread1);
}
DWORD WINAPI CNumbergeneratorDlg::Thread1(LPVOID iValue)
{
CreateNumber();
return 0;
}
??? casting for "this"
DWORD WINAPI CNumbergeneratorDlg::Thread1(LPVOID iValue)
{
(CDialog)iValue->CreateNumber();
return 0;
}
xxxxxxxxxxxxxxx
xxxxxxxxxxxxxxx
This is what I did with your guys input... thanks
void CNumbergeneratorDlg::OnBtn3()
{
//CreateThread
CNumbergeneratorDlg *pp = this;
hThread1 = CreateThread(NULL, 0, Thread1, pp, 0, NULL);
// WaitForSingleObject(hThread1,INFINITE);
// TerminateThread(hThread1,0);
// CloseHandle(hThread1);
}
DWORD WINAPI CNumbergeneratorDlg::Thread1(LPVOID iValue)
{
CNumbergeneratorDlg *pp = (CNumbergeneratorDlg*)iValue;
pp->CreateNumber();
return 0;
}
void CNumbergeneratorDlg::CreateNumber()
{
long m;
j = 0;
for(long i = 0; i < 1000;i++){
m = 0;
for(long k = 0; k < 1000000;k++){
m ++;
}
j++;
}
AfxMessageBox("Done count");
TerminateThread(hThread1,0);
CloseHandle(hThread1);
}
void CNumbergeneratorDlg::OnBtn4()
{
TerminateThread(hThread1,0);
CloseHandle(hThread1);
CString c;
c.Format("%d", j);
MessageBox(c);
}
You're trying to pass CreateThread a class method which doesn't have the signature it expects. The first argument of all methods is the same type of the this pointer, in the case of Thread1, an CNumbergeneratorDlg*.
You should:
Make the method Thread1 static, or
Move it outside the class.
Here is an article on static methods which shows how you should use static in this situation:
http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Fcplr039.htm
Here is an article that may be of use when using CreateThread:
http://adilevin.wordpress.com/2009/06/07/createthread-an-example/
I also suggest you read the following, to understand calling conventions (the '__stdcall' bit):
http://msdn.microsoft.com/en-us/library/zxk0tw93(v=vs.80).aspx
Thread1 is a non-static member function. Calling it requires an instance of your class (CNumbergeneratorDlg). That's why you get that error.
You could make Thread1 static, and pass this by parameter when creating the thread:
class CNumbergeneratorDlg {
void OnBtn3() {
hThread1 = CreateThread(NULL, 0, Thread1, this, 0, NULL);
// ...
}
public:
static DWORD Thread1(LPVOID lpdwThreadParam) {
CNumbergeneratorDlg *instance =
static_cast<CNumbergeneratorDlg *>(lpdwThreadParam);
// do something with instance.
}
};
Did you declare the function Thread1 as a static member function in CNumbergeneratorDlg? If not, please do so.
Non-static class functions have an implicit additional parameter for this. So, type casting will not work. On the other hand, static methods do not carry this parameter.
Then, you might wonder how you can access class members inside Thread1. A typical technique is passing this via iValue.
Related
Is it possible to pass a function pointer as the parameter for the freeRTOS xTaskCreate function?
I suspect I need to cast the void* pvParameters within the task before I can call it but I am not sure what such as cast would be.
class param
{
private:
//Initialized during construction to hardware specific value.
uint8_t mParam = 0;
public:
uint_8 getParam() {return mParam;}
};
void task(void* pvParameters)
{
//get hardware specific pvParameters.
uint8_t hwParam = pvParameters();
// Do task things.
}
main()
{
param p;
uint32_t result;
result = xTaskCreate(task, "Task", configMINIMAL_STACK_SIZE, (void *)&p.getParam, configMAX_PRIORITIES - 1, nullptr); //lint !e712 implicit conversion from long to int
if (result == 0)
{
//print error msg.
}
else
{
vTaskStartScheduler();
for(;;) {ASM("NOP");}
}
}
Why not using &p (address of object p) as argument to access the complete param object using a cast like this:
param& p = *(param*)pvParameters;
Beware that for a number of ports/MCUs the main stack is reused as ISR stack and main stack allocated arguments might get corrupted. Better use e.g. static/new param object.
I am a little confused on how pthread works - specifically, I am pretty sure that pthread takes in a pointer to a function that takes a void pointer as an argument (correct me if I am wrong), and I have declared my function in that way, but I am still getting an error. Here is the code I am struggling with:
void eva::OSDAccessibility::_resumeWrapper(void* x)
{
logdbg("Starting Connection.");
_listener->resume();
logdbg("Connected.");
pthread_exit(NULL);
}
void eva::OSDAccessibility::resumeConnection()
{
long t;
_listener->setDelegate(_TD);
pthread_t threads[1];
pthread_create(&threads[0], NULL, &eva::OSDAccessibility::_resumeWrapper, (void *)t);
}
The error I'm getting is:
No matching function for call to pthread_create.
You don't necessarily have to tell me how to fix the code (although that would be appreciated of course), I'm more interested in why this error is coming up and if my understanding of pthread is correct. Thanks! :)
Your function signature must be void * function (void*)
If called from c++ code, the method must be static:
class myClass
{
public:
static void * function(void *);
}
A solution to use methods that are not static is the following:
class myClass
{
// the interesting function that is not an acceptable parameter of pthread_create
void * function();
public:
// the thread entry point
static void * functionEntryPoint(void *p)
{
((myClass*)p)->function();
}
}
And to launch the thread:
myClass *p = ...;
pthread_create(&tid, NULL, myClass::functionEntryPoint, p);
So, I have been trying to figure out how c++ multi-threading works and how to apply it to the project I am working on. I am trying to accomplish creating a new thread and running a function on that thread. The function I am trying to run is called SetupInfo and takes an Individual as a single parameter. I have seen examples of this and have tried to implement them, but after multiple attempts I cannot successfully pass the parameter I need into the thread I want the function to run on. Here is what I have come up with:
Here I create a struct to store the pointer to the Individual that I need later on.
struct ThreadData
{
Individual *m_pInd;
ThreadData(Individual pInd) : m_pInd(*pInd) {}
};
Here I create a function that I can call in my program that creates the thread that runs the function SetupThreadFunction which takes a void pointer as a parameter. I am trying to pass the variable data into this function and then cast it back to ThreadData to be able to access the items of the struct.
void SetupThread(Individual input)
{
ThreadData *data = new ThreadData(input);
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) SetupThreadFunction, data , 0, 0);
delete data;
}
Here I create the function that is passed into the CreateThread function which takes a void pointer and casts it to ThreadData which can then theoretically access the threadData->m_pInd. The same pointer for data above is passed correctly into the SetupThreadFunction. However, m_pInd contains null data and not the pointer to the information that is expected. Why is that?
DWORD WINAPI SetupThreadFunction(LPVOID lpParameter)
{
ThreadData* threadData = (ThreadData*)lpParameter;
SetupInfo(threadData->m_pInd);
return 0;
}
Is there a more correct way to pass a parameter into the new win32 thread I am creating?
The correct pattern is to allocate the object with new, fill in the data (if not done through parameters to new), pass the pointer to the newly-created thread, and let the thread delete the object when it's done with it. You delete the object before you know the thread has even started!
This isn't a multithreading problem; it's a pointer problem.
This line doesn't make sense to me:
ThreadData(Individual pInd) : m_pInd(*pInd) {}
m_pInd is a pointer and yet you're initializing it with *pInd which means you want to dereference pInd, but pInd is not a pointer, let alone a pointer to a pointer. I don't see how this would even compile.
Assuming you actually meant & instead of *, as in:
ThreadData(Individual ind) : m_pInd(&ind) {}
The problem here is that you're creating a pointer to a copy of an Individual on the stack, and that copy goes away upon return from the constructor, so you have a dangling pointer.
Use std::thread.
void ThreadProc(Individual individual);
int main()
{
Individual individual;
std::thread thread(ThreadProc, individual);
thread.join();
return 0;
}
Here's a simple code example to demonstrate the points already discussed.
#include "stdafx.h" // includes <windows.h>, <string> and <iostream>
using std::string;
using std::cout;
class Individual
{
public:
string s;
};
struct ThreadData
{
Individual *m_pInd;
ThreadData(Individual* pInd) : m_pInd(pInd) {}
};
DWORD WINAPI SetupThreadFunction(LPVOID lpParameter)
{
cout << "Hi From Thread\n";
ThreadData* threadData = static_cast<ThreadData*>(lpParameter);
//SetupInfo(threadData->m_pInd);
// do delete here, once its finished with.
delete threadData;
return 0;
}
HANDLE SetupThread(Individual* input)
{
ThreadData *data = new ThreadData(input);
return CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) SetupThreadFunction, data , 0, 0);
}
int _tmain(int argc, _TCHAR* argv[])
{
cout << "Hi\n";
Individual* i = new Individual;
HANDLE h = SetupThread(i);
if(h)
{
WaitForSingleObject(h, INFINITE);
cout << "Done\n";
} else
{
cout << "Couldnt create thread\n";
}
getchar();
delete i;
return 0;
}
Bear in mind also you can use _beginthread as a simpler interface to launch a thread on Win32.
I want to pass a class object into a method of other class through a thread call, I tried but got the error can any one help me on this.please.
struct sample{
int status;
std::vector <std::string> a_row;
size_t column_count;
std::vector <std::string> column;
};
class sess {
public:
int a;
sess(int);
sess();
};
class Gen {
private:
static Gen* gen_obj;
public:
static bool Gen_InstanceFlag;
static Gen* GetInstance();
sample addition(sess);
};
/* End of Header File */
/* Beginning of cpp File */
include"Class_thread_mixing.h"
bool Gen::Gen_InstanceFlag=false;
Gen* Gen::GetInstance(){
if(!Gen::Gen_InstanceFlag){
Gen::gen_obj = new Gen();
Gen::Gen_InstanceFlag= true;
return gen_obj;
}
else {
return gen_obj;
}
}
sample addition(sess ses_obj){
sample sam;
sam.a_row.push_back("success");
sam.column.push_back("result");
sam.column_count=1;
sam.status=ses_obj.a;
return sam;
}
int main(int argc, char* argv[])
{
HANDLE myhandleA;
Gen* gen=Gen::GetInstance();
sess ses_obj(10);
myhandleA=(HANDLE)_beginthreadex(0, 0, gen->addition(ses_obj),(void*)0, 0, 0);
WaitForSingleObject(myhandleA, INFINITE);
CloseHandle(myhandleA);
getchar();
return 0;
}
This is my code and I am getting an error like "error C2665: '_beginthreadex' : none of the 2 overloads could convert all the argument types"
Can any one suggest me who can I pass the object of sess to a function in a thread call and how can I get the results from the thread.
Thanks for your answers..
s there any option such that I can call the function directly in the thread without calling a standalone thread function, like I mentioned in my code [(HANDLE)_beginthreadex(0, 0, gen->addition(ses_obj),(void*)0, 0, 0) ]
I need to call addition method in the thread can any body help me on this.
The problem here is that instead of passing a function to the called by _beginthreadex, you are actually calling that function with an argument, causing the _beginthreadex function to be called with the return value from Gen::addition. This structure is if course not a function, and so the compiler complains.
The solution to this is not straightforward though. First of all because a stand-alone function (as required by _beginthreadex is not the same as a class member function. The reason being that all class member functions actually have a "zeroeth" hidden argument, and that is an instance of the class that becomes the this pointer that can be used inside member functions.
The best solution is probably to create a stand-alone function, which takes as argument a pointer to a structure, and the structure contains the object instance, and the argument to the actual member function.
Something like this:
struct call_data
{
sess sess_obj;
Gen* gen_obj;
};
static void thread_function(void* data)
{
call_data *call = reinterpret_cast<call_data*>(data);
// Do the actual member function call
call->gen_obj->addition(call->sess_obj);
}
int main()
{
...
call_data call = { ses_obj, gen };
myhandleA=(HANDLE)_beginthreadex(0, 0, thread_function, &call, 0, 0);
...
}
Entry point for thread can't be a class method. it has to be static or at global scope.
You need to define a static method like this
static unsigned ThreadEntry(void* arg)
{
sess *p = (sess*)arg;
Gen::GetInstance()->addition(*p);
}
and run the thread like this:
sess ses_obj(10);
myhandleA=(HANDLE)_beginthreadex(0, 0, ThreadEntry,(void*)&ses_obj, 0, 0);
I have a function called by a thread.this function has a unique argument which is queue::my_queue . So I need to perform a cast on void pointer in the method called by the thread as follows:
void *AddPacket(void *Ptr)
{ queue<int> my_queue = (queue*)Ptr ;
my_queue.push(byte) ;
}
and in the main, I do:
int main()
{ // do business
pthread_create(&thread, NULL, &AddPacket, (void*)queue) ;
}
But both conversions are wrong.
the first conversion leads to the error:
request for member ‘push' in ‘my_queue’, which is of non-class type ‘queue*’
and the second one:
invalid cast from type ‘queue’ to type ‘void*’
How can I solve the problem?
You try to cast object type to pointer type. It is not allowed. I guess you are new to C++, so I post corrected code here to unpuzzle you and get you going, but please read a book on C++:
queue<int>* my_queue = (queue<int>*)Ptr ;
my_queue->push(byte) ;
pthread_create(&thread, NULL, &AddPacket, &queue) ;
Remember to read about pointers on C++ :)
Try:
queue<int> *my_queue = (queue<int> *)Ptr ;
my_queue->push(byte) ;
pthread_create(&thread, NULL, &AddPacket, (void*)&queue) ;
.. something along those lines, anyway
You need to change both the thread function and the thread creation:
// thread entry point:
void *AddPacket(void *Ptr)
{
reinterpret_cast<std::queue<int>*>(Ptr)->push(byte);
}
// thread creation:
std::queue<int> q;
pthread_create(&thread, NULL, &AddPacket, &q);
// ^^^^ **pointer** to "q";
// conversion to void* is implied