I'm interested to know if it is possible to call _beginthreadex with function pointer that is not known and NOT based on class design.
For example:
#include <stdio.h>
#include <process.h>
#include <windows.h>
int myThread(void* data)
{
printf("ThreadID: %d \n", GetCurrentThreadId());
return 1;
}
HANDLE callIntThreadFunc(void (*pFunction)(LPVOID), LPVOID pvFuncArgs)
{
//Expected to fail compilation due to __stcall
return (HANDLE) _beginthreadex(NULL, NULL, pFunction, (LPVOID) pvFuncArgs, NULL, NULL);
}
int main(int argc, char *argv[])
{
HANDLE hThread = callIntThreadFunc(myThread, NULL);
WaitForSingleObject(hThread , INFINITE);
return 0;
}
I'm aware that _beginthread can work when converting the function (by the following code):
return (HANDLE) _beginthread((void (*)(void*)) pFunction, 0, (LPVOID) pvFuncArgs);
So my question is if it possible to use _beginthreadex in such cases and if so how?
Any thoughts will be appreciated.
What do you mean by "not known and NOT based on class design"? For one, _beginthreadex() is not an object-oriented API.
As to the known part, well: when using a function pointer the compiler will at least need to know where the pointed function is (its address) and how to call it (what parameters it expects and what values it returns). If you deviate from that contract, nothing is guaranteed: the call might end up working reliably or not depending on the generated code.
In your example, _beginthreadex() is telling you that it expects a function that uses the __stdcall convention, takes an address as a parameter and returns no results. You're giving it a function that returns an int and takes an address parameter but (assuming default compiler settings) uses the regular C calling convention instead of __stdcall: therefore some stack corruption is likely. By using the cast, you're just telling the compiler to stop complaining and generate the call (whatever the consequences).
If you want to do something like in your example, it's safer to give _beginthreadex() a __stdcall function that calls whatever function you actually want to use.
Found the answer i was looking for - it is doable and its conversion matter as Lois said.
The following code make it happen, compile and spread the thread ;-)
return (HANDLE) _beginthreadex(NULL, NULL,(unsigned (__stdcall*)(void*)) pFunction, pvFuncArgs, NULL, NULL);
Thanks all.
Related
I have the following code:
unsigned long ClassName::fn_StartTesterPresentThread()
{
// m_hTesterPresent is a HANDLE
if (m_hTesterPresent == NULL)
{
DWORD dwThreadId = 0;
m_hTesterPresent = CreateThread(NULL, 0, th_TesterPresent, this, 0, &dwThreadId);
}
return ACTION_SUCCESS;
}
The CreateThread function is Windows-specific, but the code needs to be ported to Linux/non-platform-specific.
I now need a way to create a boost::thread and pass it into the HANDLE m_hTesterPresent.
I was thinking about something like this:
unsigned long Class::fn_StartTesterPresentThread()
{
if (m_hTesterPresent == NULL)
{
DWORD dwThreadId = 0;
boost::thread threadTesterPresent(&m_hTesterPresent);
threadTesterPresent.join();
}
return ACTION_SUCCESS;
}
Is this the correct way? Sadly, I can't yet compile or test because I still have other parts of the project to port.
Furthermore, the project is a DLL and I don't have the client yet that calls the functions in the DLL.
Any help appreciated!
The argument to boost::thread should be a function to call, here th_TesterPresent.
If you are porting this code to non-Windows environments, I suggest you use typedefs to distinguish between the different kinds of HANDLEs.
Then you can have:
#ifndef WINDOWS
typedef boost::thread* THREAD_HANDLE;
typedef boost::mutex MUTEX_HANDLE;
#else
typedef HANDLE THREAD_HANDLE;
typedef HANDLE MUTEX_HANDLE;
#endif
and store THREAD_HANDLE / MUTEX_HANDLE values in various place. Instead of calling OS-specific functions, you can then call generic "createThreadHandle" functions that dispatch to different functions depending on the OS.
Alternatively, you could port your code to an OS-agnostic framework like boost and solve two problems in one go.
In order to implement a thread class(In C++98 and Windows.h). I have something like this:
Thread::Thread(_beginthreadex_proc_type fn)
{
m_raw = fn;
m_args = 0;
m_handle = 0;
m_id = 0;
}
The code above works fine it takes a function that not receive parameters, and with the next code it function is called by a new thread:
void Thread::Join()
{
m_handle = (HANDLE)_beginthreadex(0, 0, m_raw, (m_args ? m_args : 0), 0, 0);
if (m_handle) WaitForSingleObject(m_handle, INFINITE);
}
This code also works fine with functions that don't take any parameter.
Now my question is about how can i in C++98 receive variadic parameters in my constructor and save them.
And NO i can't use modern c++ if that was the case I din't need help. So plz don't give me solutions implemented with c++11 or higher.
Update
Now I'm trying a Java style solution in that every Thread is a IRunnable that have a pure virtual function named Run. And thread is almost the that this implementetation with the diff that is an abstract class. In this way can i avoid parameters because I don't pass the function instead of that I write another class that inherits from Thread and implements Run.
The code look like:
The interface
struct IRunnable
{
virtual void Run() = 0;
};
Thread class
class Thread : public IRunnable
{
HANDLE m_handle;
DWORD m_id;
typedef unsigned (__stdcall *Function)(void*);
_beginthreadex_proc_type m_raw;
void* m_args;
public:
Thread();
~Thread();
Thread(_beginthreadex_proc_type, void*);
Thread(_beginthreadex_proc_type);
unsigned GetId();
virtual void Run() = 0;
void Join();
unsigned int __stdcall call(void*);
};
Call only is a wrapper to call Run function member
unsigned int __stdcall Thread::call(void* data)
{
Run();
return 0;
}
My problem is here:
void Thread::Join()
{
m_handle = (HANDLE)_beginthreadex(0, 0, &this->call, 0, 0, 0);
if (m_handle) WaitForSingleObject(m_handle, INFINITE);
}
When i compiling in vs2019 the code above produce the next error:
error C2276: '&': illegal operation on bound member function expression
error C2660: '_beginthreadex': function does not take 5 arguments
For your edited question, the reason you're getting a compile error is because you're trying to send the address to a member function of your Thread object. You can't take pointers to member functions and use them without also keeping the object pointer around. Instead, you should make a global function that takes a Thread* as its argument, send a pointer to that function, and let it call your runnable.
unsigned thread_entry(void* thread_ptr)
{
Thread* thread = (Thread*) thread_ptr;
return thread->call();
}
void Thread::Join()
{
m_handle = (HANDLE)_beginthreadex(0, 0, thread_entry, this, 0, 0);
if (m_handle) WaitForSingleObject(m_handle, INFINITE);
}
P.S. It's usually best to ask new questions instead of editing old ones if the question is significantly different, which yours is.
If you look at pretty much any thread library, they very rarely support sending multiple arguments; you usually send a pointer to something, and if you want many things, you make a struct containing many things and send a pointer to it.
However, if you really want this, you could use the C varargs functions to iterate over all variadic arguments, and allocate a linked list with them, or allocate an array of them, or whatever other data structure you want. Then, send a pointer to that to your thread entry function. Your function would still be taking just one pointer, though.
In C, there is no easy way to construct a va_list, which is how variadic arguments are sent around. You can't just send the va_list you have on your main thread, because that memory won't be alive by the time it reaches your new thread. There is also no good way to expand a va_list to fill function arguments.
Btw, I realize you're using C++, but as far as C++98 goes, its varargs support is basically the same as in C, which is why I'm mentioning C in my answer.
How do I start a thread using _beginthreadex(), making it execute void myFunction(wchar_t *param);? I try to use this:
_beginthread(NULL, 0, myFunction, L"someParam", 0, &ThreadID);
but there is compilation error:
error C2664: 'beginthreadex' : cannot convert parameter 3 from 'void (_cdecl *)(wchar_t *)' to 'unsigned int (__stdcall *)(void *)'.
How I can resolve this error? I seem able to do _beginthread((void(*)(void*))myFunction, 0 , (void *)L"someParam");. But for _beginthreadex() these casts don't seem to work. What do
I need to do?
This code doesn't output anything. What's wrong?
unsigned int __stdcall myFunction( void *someParam )
{
printf("Hello world!");
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
_beginthreadex(NULL, 0, myFunction, L"param", 0, NULL);
return 0;
}
_beginthreadex requires a function that uses the __stdcall calling convention, not the __cdecl calling convention, which is the default. To fix it, declare your thread procedure with the __stdcall calling convention:
unsigned int __stdcall myFunction(void *arg)
{
...
}
Do NOT cast the function pointer you're passing into _beginthread or _beginthreadex: a function pointer cast is a bug waiting to happen.
Function prototype requirements for each Microsoft CRT thread launch functions are:
_beginthread: void __cdecl procname(void * arg);
_beginthreadex: unsigned int __stdcall procname(void *arg);
You should also be aware of the differences between the two.
_beginthread: allocates a new thread and invokes the thread procedure passed as the argument. Using this API the thread-creation parameters are somewhat limited. The return value of this function is a uintptr_t, but is actually a Windows thread handle of type HANDLE. It must be cast to a HANDLE variable to be used in such functions as WaitForSingleObject, etc. When the thread procedure finishes through normal function-exit the thread handle is automatically closed for you by the runtime. This is important. Although this function returns a thread handle just like _beginthreadex, it is conceivable for the thread to start and finish before you can do anything with the handle (such as a wait, suspend, etc.). Once the thread procedure finishes the RT will close the handle, and therefore your local variable holding the initial returned handle is now invalid.
_beginthreadex: allocates a new thread and invokes the thread procedure passed as the argument. This version allows significantly more control over how the thread is created, including the stack size, initial suspended state, etc. The return value of this function is a uintptr_t, but is actually a Windows thread handle of type HANDLE. It must be cast to a HANDLE variable to be used in such functions as WaitForSingleObject, etc. When the thread procedure finishes through normal function-exit the thread handle is NOT automatically closed for you by the runtime. You are responsible for closing the thread handle returned by this function, and should do so as soon as it is no longer needed.
Which to use: Use _beginthread if you have no need for the thread handle to be used in Wait functions and such, and have no special thread-creation needs (like creating a thread with an initially-suspended state). Use _beginthreadex when you need a wait'able thread handle, finer control over the creation parameters, etc.
EDIT: Sample for the OP
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <process.h>
unsigned int __stdcall MyThread(void *p)
{
_tprintf(_T("%s\n"), p);
_tprintf(_T("Thread finishing!\n"));
return 0;
}
int _tmain(int argc, TCHAR *argv[])
{
HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, MyThread, _T("Hello, World!"), 0, NULL);
if (hThread != INVALID_HANDLE_VALUE)
{
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
_tprintf(_T("Thread finished!\n"));
}
return 0;
}
As in the other answer above, don't forget to wait for your thread to finish before _tmain exits, or you likely will see no output.
I recently learnt that ::_beginthreadex() is always preferable to ::CreateThread(), so I changed all my calls that used ::CreateThread().
The only downside is that I no longer see the thread function's name in Visual Studio's Threads window making it hard to quickly identify threads. I assume this was somehow done automatically by the debugger when I used ::CreateThread(), since the parameters are exactly the same, I just changed the name of the function used.
Is there any way to keep using ::_beginthreadex() and to see the thread's name in the Threads window of Visual Studio?
This happens because _beginthreadex() calls CreateThread() with its own thread function that calls the one you specify (so the debugger uses the _threadstartex function name - the one that _beginthreadex() invokes).
You can manually set the thread name yourself using the SetThreadName() example from MSDN. What you might want to do is create your own wrapper for _beginthreadex() that maybe looks something like:
uintptr_t startthreadex(
void* security,
unsigned stacksize,
unsigned (__stdcall * threadproc) (void *),
void* args,
unsigned flags,
unsigned * pThread_id,
char* thread_name)
{
unsigned alt_thread_id;
if (!pThread_id) {
pThread_id = & alt_thread_id;
}
uintptr_t result = _beginthreadex(security, stacksize, threadproc, args, flgas, pThread_id);
if (result == 0) return result;
SetThreadName( *pThread_id, thread_name);
}
Now you can call startthreadex() instead of _beginthreadex() and pass it a thread name. A small advantage to this is that if you use the same function to run several threads, you can easily give them each unique names that reflect the parameters passed ot the thread or whatever.
If you want the thread name to automatically take be the thread proc function name as the debugger's thread name, you could make a wrapper macro that stringizes the function name parameter (all it takes is another level of indirection or to to solve any problem...).
Here's SetThreadName() (it's from http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx):
//
// Usage: SetThreadName (-1, "MainThread");
//
#include <windows.h>
const DWORD MS_VC_EXCEPTION=0x406D1388;
#pragma pack(push,8)
typedef struct tagTHREADNAME_INFO
{
DWORD dwType; // Must be 0x1000.
LPCSTR szName; // Pointer to name (in user addr space).
DWORD dwThreadID; // Thread ID (-1=caller thread).
DWORD dwFlags; // Reserved for future use, must be zero.
} THREADNAME_INFO;
#pragma pack(pop)
void SetThreadName( DWORD dwThreadID, char* threadName)
{
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = threadName;
info.dwThreadID = dwThreadID;
info.dwFlags = 0;
__try
{
RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info );
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
There is no particular advantage with using _beginthreadex over CreateThread. The CRT functions would eventually call CreateThread only.
You should read:
Windows threading: _beginthread vs _beginthreadex vs CreateThread C++
http://www.codeguru.com/forum/showthread.php?t=371305
http://social.msdn.microsoft.com/forums/en-US/vclanguage/thread/c727ae29-5a7a-42b6-ad0b-f6b21c1180b2
hello i want to get startet with programming with WIN32, therefore i wrote a programm that creates a process but in the line of code where i create the process the programm gets an error an dosn't work (abend). i don't know if the code in programm 1 is wrong or the code in the second programm that should be created by the first. ( I don't know if the code in the first programm after "createprocess" is right because i didn't get further with debugging, because in this line i get the error.(i tested it without the cout,waitforobject and close handle but i didn't work either )).
First Programm:
#include <iostream>
#include <windows.h>
#include <string>
using namespace std;
void main()
{
bool ret;
bool retwait;
STARTUPINFO startupinfo;
GetStartupInfo (&startupinfo);
PROCESS_INFORMATION pro2info;
ret = CreateProcess(NULL, L"D:\\betriebssystemePRA1PRO2.exe", NULL, NULL, false, CREATE_NEW_CONSOLE, NULL,
NULL, &startupinfo, &pro2info);
cout<<"hProcess: "<<pro2info.hProcess<<endl;
cout<<"dwProcessId: "<<pro2info.dwProcessId <<endl;
retwait= WaitForSingleObject (pro2info.hProcess, 100);
retwait= WaitForSingleObject (pro2info.hProcess, 100);
CloseHandle (pro2info.hProcess);//prozesshandle schließen
retwait= WaitForSingleObject (pro2info.hProcess, 100);
ExitProcess(0);
}
Seconde Programm:
#include <iostream>
#include <windows.h>
#include <string>
using namespace std;
void main()
{
int b;
b=GetCurrentProcessId();
cout<<b<<endl;
cout<<"Druecken Sie Enter zum Beenden"<<endl;
cin.get();
//warten bis Benutzer bestätigt
Sleep (700);
ExitProcess(0);
cout<<"test";
}
Thanks in advance
Notice the type of the lpCommandLine parameter to CreateProcess -- it is LPTSTR, not LPCTSTR, i.e. it is not const.
This means that CreateProcess reserves the right to actually modify the contents of lpCommandLine. However, you have provided a pointer to a string literal as parameter, and string literals are immutable (they come from your program's read-only data segment and attempts to alter them will typically result in an access violation error.)
To fix this, simply change your code not to use an immutable string literal:
wchar_t wcsCommandLine[] = L"D:\\betriebssystemePRA1PRO2.exe";
ret = CreateProcess(NULL, wcsCommandLine, NULL, NULL, ...
Interestingly enough, CreateProcessW (UNICODE) attempts to write to lpCommandLine whereas CreateProcessA (ANSI) does not, and surprise -- your first program is built as UNICODE (were you to build it as ANSI it would work out of the box, at least on Windows XP.)
I can confirm that, with the above modification, your code works.
Also note that:
unless you need to specify D:\\betriebssystemePRA1PRO2.exe's window title, position etc. you do not need to supply a STARTUPINFO structure at all, you can simply pass lpStartupInfo as NULL and a default will be used
you should not be calling WaitForSingleObject on a closed handle
You must set the size of the startupinfo struct:
startupinfo.cb = sizeof(startupinfo);
Maybe this is why CreateProcess is failing.
And by the way - why are you calling GetStartupInfo? You should just zero out the memory of startupinfo (besides setting the size as mentioned above).
See an example here.