views:

380

answers:

2

Hi;

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?

+1  A: 

[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().

Steffen
In fact, my callback accesses static Class instance and change a value in it and exits while main thread sleeps. Can this cause problem?
whoi
As long as it's a simple value change (no delete/new or so) and you are sure that the other thread is not modifying it at the same time, I'd say that should cause no problem.
Steffen
Incorrect. Statically linked libraries see the exact same malloc/free and new/delete (even if overridden) functions as the program code and do not have their own heaps (you'd have to do quite a bit of work to make each static library have it's own heap actually).
Adisak
+1 I agree. Any libs you write should by build against the dynamic version (DLL) of the standard libs. About 10 years ago it was a real pain to write windows code because each lib had its own heap and memory allocated by a lib had to be deallocated by the same lib or the result was memory corruption and a crash. The solution to this problem was the DLL of the standard lib so that the whole application used the same heap. So use the solution MS spent so long devloping to get write so you youngsters can write code much easier (do not go down the dark side again). ;-)
Martin York
@Adisak: Only true if the link against the DLL version of the standard lib. If you statically link against the standard lib you get your own heap.
Martin York
@Martin. The problem mentioned (with extra heaps) do not happen with statically linked user-libs (whether the code is linked dynamically or statically to the c-stdlibs). They happen when you make a dynamically linked user-lib that is statically linked to c-stdlibs. Then you end up with a heap in the user program and a separate heap in the dynamically linked user-lib. In this case allocation from one (user code) and freeing in another (user dll static linked to clib) will cause corruption. However, this can never happen for statically linked user-libs as is the case the question describes
Adisak
This simple rule is: If you make a DLL that statically links to clibs, that DLL will have it's own heap. If you make a static lib that links to user code, that static lib will share the same heap as the user code.
Adisak
Actually I agree with Adisak. I stumbled across this problem a few times, but of course that was when the library itself was linked dynamically which is not the case here.
Steffen
@Adisak: I disagree. It does not matter if your lib is static or dynamic, it only matters how you link against the standard libs (when you build the lib). If you link the standard libs statically it will have its own heap. This is because of how the memory management is actually implemented. The linker imports all the heap management code into your lib (including the global's were the info is stored). Thus it set up its own heap in the library. This of course does not happen if you use the DLL version of the standard libs as everybody shares the same heap code.
Martin York
@Martin: Using DLL stdlibs in both 3rd-party DLL's and user code ensures only one heap. But linking a 3rd-party library statically to user code and linking to stdlib statically puts all the 3rd-party library / user code / and stdlib in the same code and data segments. You can't have multiple functions with same name in same segment - thus they all share identical malloc (and associated data) and operate from a single heap. Go try it yourself. The only way I know to get the multiple heap fiasco is thru making (or using) a DLL's that is statically linked to stdlib.
Adisak
@Martin: FWIW, also if you build a static lib, you *DO NOT* link stdlibs to your static lib. If you build a DLL, you *DO* link stdlibs to your DLL. Therein lies the difference and is why you can get the problems with the DLL's (because stdlib can be linked to both DLL and user code and they have different entry points for same function name and duplicated associated data).
Adisak
A: 

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.

Adisak