I have a C static library with,
A callback definition:
typedef void (*HandleEvents) (enum events eventID, int msgSize, char *msg);
A function in the library:
int init(HandleEvents _handleEvents)
And another C++ GUI developed in VS. which links this static lib and calls init function of the lib giving a function pointer.
init(&CGateway::handleEventsFunc);
where CGateway::handleEventsFunc is a static class function.
In a thread in the static lib calls this callback of the C++ GUI. But I got errors of heap corruption.
In sum, there are 2 threads, one in static library and one in Main GUI app. Static library calls Main GUI's class function.
So what is the correct way of calling callback function in a thread?
[incorrect statement about multiple heaps, as pointed out by Adisak, deleted]
One thing to check is, that you are not doing anything GUI related from the worker thread. Accessing windows is only safe from the main thread where they were created. If you have to update GUI stuff, you have to decouple that by using PostMessage().
Make sure to use a mutex or other form of thread protection for any variables that can be modified by one thread and are used (read or modified) by another thread.
In multithreaded code, heap corruption is quite often a symptom of code that is not thread-safe accessing memory.
Related
I have a shared C library, that read data from COM port in a separate thread.
And a C++ wxWidget application, that wait a data from lib and render it in UI.
I need to make a callback function, that lib will call, when collect a correct packet of data.
I've made a static var in wxWidget frame class, which contain a pointer to the object of this class and a static method, pointer to which I give to a library as a callback. Thats callback work, but in this cause I can't modify the UI. The program crashed with SIGABRT signal. As I see, it's a bad way to modify an wxWidgets UI from a non-main thread. But I dont know how to do it another. Can you help me? Thank you.
Yes, you can only use wxWidgets GUI functions from a single (commonly called "main", but it doesn't have to be the actual main thread of the application, just the one from which wxWidgets was initialized) thread. The only thing you can do from another thread safely is to post an event to the GUI thread asking it to perform something on this thread behalf, see wxQueueEvent().
Since wxWidgets 3.0 there is a convenient wrapper, using the same underlying mechanism, called CallAfter(). Especially if you use C++11, it's very simple to use as you can just pass it the code to be executed in the main thread directly, e.g.
void MyThreadCallback(void* data)
{
wxTheApp->CallAfter([=]() {
wxMessageBox("This is safe because we're in the main thread now");
// Do whatever you need to do with "data"
});
}
I have a single class which does all the required initialization.
currently i have declared a global object of this class type, which is being instantiated on library load.
I've seen other ways, like delaring
BOOL APIENTRY DllMain
entry point for the shared library, and does the actual initialization on process attach.
does this differ from letting the implicit global initialization to its job? which way is better?
This is what happens during C++ DLL startup:
System calls DLL's entry point, generated by you compiler
Entry point calls DllMainCRTStartup (name may differ), which initializes C/C++ runtimes and instantiates all global objects.
DllMainCRTStartup then calls user-defined DllMain.
I personally prefer DllMain, because this way I can explicitly control order of initialization. When you use global objects in different compilation units, they will be initialized in random order which may bring some unexpected surprises 10 minutes before the deadline.
DllMain also let's you do per-thread initialization, which you can not achieve with global objects. However, it is not portable to other platforms.
P.S. You do NOT need mutex in DllMain, as all calls to it are already serialized under process-global critical section. I.e. it is guaranteed two threads will not enter it at the same time for any purpose. This is also the reason why you should not communicate with other threads, load other libraries etc. from this function; see MSDN article for explanation.
A couple of things that should never be done from DllMain:
Call LoadLibrary or LoadLibraryEx (either directly or indirectly). This can cause a deadlock or a crash.
Synchronize with other threads. This can cause a deadlock.
Acquire a synchronization object that is owned by code that is waiting to acquire the loader lock. This can cause a deadlock.
Initialize COM threads by using CoInitializeEx. Under certain conditions, this function can call LoadLibraryEx.
Call the registry functions. These functions are implemented in Advapi32.dll. If Advapi32.dll is not initialized before your DLL, the DLL can access uninitialized memory and cause the process to crash.
Call CreateProces. Creating a process can load another DLL.
Call ExitThread. Exiting a thread during DLL detach can cause the loader lock to be acquired again, causing a deadlock or a crash.
Call CreateThread. Creating a thread can work if you do not synchronize with other threads, but it is risky.
Create a named pipe or other named object (Windows 2000 only). In Windows 2000, named objects are provided by the Terminal Services DLL. If this DLL is not initialized, call to the DLL can cause the process to crash.
Use the memory management function from the dynamic C Run-Time (CRT). If the CRT DLL is not initialized, calls to these functions can cause the process to crash.
Call functions in User32.dll or Gdi32.dll. Some functions load another DLL, which may not be initialized.
Use managed code.
You need a static boolean initialization variable and a mutex. Statically initialize "initialized" to 0. In your DllMain(), make a call to CreateMutex(). Use bInitialOwner=0 and a unique name for lpName that's unique to your application. Then use WaitForSingleObject() to wait for the mutex. Check if initialized is non-zero. If not, do your initialization, and then set initialized to 1. If initialized is non-zero, do nothing. Finally, release the mutex using ReleaseMutex() and close it using CloseHandle().
Here's some pseudo-code, with error and exception handling omitted:
initialized = 0;
DllMain()
{
mutex = CreateMutex(..., 0, "some-unique-name");
result = WaitForSingleObject(handle, ...);
if (result == WAIT_OBJECT_0) {
if (!initialized) {
// initialization goes here
initialized = 1;
}
}
ReleaseMutex(mutex);
CloseHandle(mutex);
}
hi i would recommend u to prefer a signleton class where u can only create a single object of a class and use it. Sigleton class can be created with a private constructor. Now suppose ur class A is a singleton class its object can be used in a constructor of each Class which u want to initialize. Please give us some sample code so other may help u better.
I rewriting some code that i written a long time ago.
The code is a class that start another worker thread with AfxBeginThread. When the thread ends, it needs to return it work to the calling class.
Actually when the thread ends it send a message by PostMessage with its results to the called class.
But this way is really dependent of MFC, and to do this my class have to implement all the MFC stuffs.
May be correct if instead of send a message it directly call a non-static method of this class ?
Rather than trying to call a method directly (which will introduce a whole new set of threading problems of its own), try using the native Win32 ::PostMessage() instead of the MFC implementation of the same function. Any thread can call ::PostMessage() to deliver a message to another thread safely.
It sounds as though you want to use regular threading primitives, not window messaging primitives.
Which version of AfxBeginThread are you using? If you pass it a class instance, you should be able to access the members of that class directly once you know its finished running. If you passed it a function pointer, you can pass any class pointer in with the lParam parameter, then use that as a communication context.
You just want to make sure that when you access the class you do it in a thread safe manner. If you wait till the thread has ended you should be fine. Otherwise you could use Critical Sections or Mutexes. See the MSDN article on thread synchronization primitives for more info.
I created a thread using CreateThread() with standard function prototype
DWORD WINAPI func(LPVOID param);
When I call TForm's members sometimes it crashes with access violation.
I do not want use Embarcadero's TThread style functions, prefer to win32 std api.
What synchronize/other conditions I should met to successfully call TForm's or its descendants members?
Thanks
Calling VCL methods in threads other than the main thread is not supported.
You need to find a way to keep all your VCL access in the main thread. One commonly used technique is the Synchronize() method. You could also send windows messages since they will always be marshalled across to the thread that owns the window.
I imagine that it's the same in C++ Builder as it is in Delphi, but in Delphi it is preferable to call BeginThread() rather than CreateThread(). BeginThread() is a lightweight wrapper of CreateThread() but the main thing it does for you is to set the IsMultiThread global variable. If you do insist on calling CreateThread() then you must set IsMultiThread true first.
I am just trying to understand some source code written in C++. I am a bit familiar
with C++, however, the following code sequence is absolutley new to me. A guess would be
that here I register some thread routine with the kernel, ptest->Run(). Could that be right?
static unsigned int __stdcall ThreadProc(void *lParameter)
{
CTest *ptest;
ptest= (Ctest *)lParameter;
ptest->Run();
return 0;
}
CTest::CTest(int n)
{
...
}
A bit simplified but a thread is a function, in this case ThreadProc. When the thread starts, the function is called and when the function exits the thread dies.
In this case, someone has started a thread with CreateThread, begin_thread or something else and passed in a pointer to a class called CTest as an argument. The thread then casts it back to a CTest* (as you can see the argument is delivered by the CreateThread API as a more generic void*) and calls the CTest::Run method before exiting.
Edit: Also, except for the "__stdcall" declaration, this is not very Windows specific. Threads in C and C++ works more or less like this on all OSes.
This is a function signature that would be used to define a function that is exported from a DLL or used as a callback function. In this case it is probably going to be used a the main loop of a worker thread.
the __stdcall keyword indicates that the function call is passed on the stack using the stdcall calling convention in Windows (same as used by methods exported from the Win32 API)
OOPS: this link doesn't play nice with markdown http://msdn.microsoft.com/en-us/library/zxk0tw93(VS.80).aspx
Not quite. This is your thread function:
static unsigned int __stdcall ThreadProc(void *lParameter)
It will be executed an different thread than whatever caused it. Calling code creates an object of type CTest, creates a thread that runs ThreadProc, which in turn runs ptest->Run();
ThreadProc is just a convenience wrapper to launch ptest->Run(). (Because otherwise it is kinda hard to use pointers to member functions)
What OS? Looks like a Windows sample, if so begin_thread(), or CreateThread or...several
The code you show declares a pointer to a CTest class object, converts the input parameter into one of those, then calls its run method.
The why this is done is the tricky part. Normally you wouldn't write code like this, however, the profile of ThreadProc is that of a thread's main entry point. For one of those, Windows doesn't give you any choice for the parameter profile of it, and it can't be a class member.
What you have there is fairly standard code to convert a thread entry-point callback from the Windows' required form into a class method call.
For a full discussion of this, see my (accepted) answer for the question: Passing Function pointers in C++