I want to use a CRITICAL_SECTION within a DLL function declared as extern
"C". With EnterCriticalSection I get an Access violation exception even
though I have initialized the CRITICAL_SECTION object before.
My CRITICAL_SECTION object is declared in a header file as follows:
static CRITICAL_SECTION csCalibrate;
The initialization in DllMain():
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
InitializeCriticalSection(&csCalibrate);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
DeleteCriticalSection(&csCalibrate);
break;
}
return TRUE;
}
The function code:
extern "C" int BEADALIGNMENT_API FindRotationCenter( const char* const
FileAngleOne, const char* const FileAngleTwo, double Theta, double& PosX,
double& PosY, double& PosZ )
{
EnterCriticalSection(&csCalibrate); // raises "Access violation writing
location 0x00000010"
// ...
LeaveCriticalSection(&csCalibrate);
}
DllMain is executed. The CRITICAL_SECTION object is initialized. But in my
FindRotationCenter function it reappears as uninitialized. Any idea?
Thanks for your help,
Fabian
You are deleting the critical section on thread attach and thread
detach. I think you missed a couple of break; lines there. :)
BTW, if your DllMain doesn't do anything on thread attach/detach then
you can improve performance a bit by calling DisableThreadLibraryCalls
() during process attach.
"Fabian" <Fab...@discussions.microsoft.com> wrote in message
news:267FE375-2B69-40BE...@microsoft.com...
//Daniel
"Fabian" <Fab...@discussions.microsoft.com> wrote in message
news:267FE375-2B69-40BE...@microsoft.com...
It means each source file gets it's *own* copy of the variable.
This, I believe, explains the AV - the variable that gets initialised
is in one source file and is a *different* variable to the one in the
FindRotationCenter.
Roger.
> You are deleting the critical section on thread attach and thread
> detach. I think you missed a couple of break; lines there. :)
You're right. I overlooked that. Thanks very much.
Fabian
"rogero" wrote:
If I only declare it global in the header file the linker strikes:
Error 1 error LNK2005: "struct _RTL_CRITICAL_SECTION csCalibrate"
(?csCalibrate@@3U_RTL_CRITICAL_SECTION@@A) already defined in
dllmain.obj FindRotationCenter.obj BeadAlignment
How else do I solve this?
Thx,
Fabian
declaration in header file:
extern "C" CRITICAL_SECTION csCalibrate;
definition in cpp file:
CRITICAL_SECTION csCalibrate;
"Fabian" <Fab...@discussions.microsoft.com> wrote in message
news:7C4EE0DA-B153-43D9...@microsoft.com...
> As you have discovered, declaring variables in header files is a bad idea.
> In this case, the same header file being included in multiple compilation
> units (.c or .cpp source files) causes multiple declarations of the same
> variable; unless, as when you specified static, the declarations are local
> scope (internal linkage) to the compilation unit. To find out more, read
> the C or C++ spec or some of the commentary in MSDN.
Sure, I usually don't use globals at all (if Singletons don't count). But in
this specific case with a synchronization object across different C functions
I didn't come up with an alternative solution. Can you give me a hint?
extern CRITICAL_SECTION g_myCS;
and in ONE source file you define it (without "extern"). That's the
way to go.
You can, however, use a class construct:
class CCritSect
: public CRITICAL_SECTION
{
public:
CCritSect() {
::InitializeCriticalSection(this); }
~CCritSect() {
::DeleteCriticalSection(this); }
};
Then you use in the header file "extern CCritSect g_myCS;", and in one
CPP file "CCritSect g_myCS;", and you don't need to care about
initialization etc. in WinMain(), this is done by the C startup code
(runtime).
Christian
"Fabian" <Fab...@discussions.microsoft.com> wrote in message
news:99C39F39-E472-46DF...@microsoft.com...
"Christian Kaiser" <bc...@gmx.de> wrote in message
news:OiTGf$s$JHA....@TK2MSFTNGP05.phx.gbl...