C++/CLI WinForms app + native static library with singletons = cra

G

Guest

Hello everyone,
I've been trying for some time now to move to C++/CLI, but I have several
large legacy C++ static libraries I need to use. When I set up a simple
solution with a C++/CLI Winforms app and a C++ native static library, they
work well together _unless_ I have, it seems, any static variables defined in
any function in the native library.
The libraries I'm trying to use all have Meyers Singletons in them, so they
need to have static variables in some functions. The libraries depend on
having singletons with destructors that work, hence the need for Meyers
singletons.

I've reduced my sample app to a very simple one that shows the crashes I
get, and I'd be happy to send that to anyone who wants it.
Here's the essential code, though.

The WinForms main app has just one button, whose click function contains this:
NativeSingleton& s = NativeSingleton::Instance();
(there's more, but the app crashes on this first line.)

The native library's cpp file contains this:
NativeSingleton& NativeSingleton::Instance()
{
// This function (and class) uses a Meyers Singleton so its destructor
will
// work properly (not thread safe as written).
static NativeSingleton theSingleton;
return theSingleton;
}
....and as usual for a singleton, it's header hides the constructor for
"NativeSingleton" and declares Instance() as static.
I think that code summarizes my problem; I'd be happy to go into more detail
if anyone wants it.

Thanks very much for _any_ insight anyone can give me.
 
J

Jeffrey Tan[MSFT]

Hi Gordo,

Can you tell me what error do you get during the crash? Anyway, since you
have a little sample project, please feel free to attach it in the
newsgroup through Outlook Express or send it to me at:
(e-mail address removed)(remove "online."). I think the sample project
will provide more information about this problem.

Thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

Thanks for your help, Jeffrey.
I realized later that I should have said more about the error, which is an
interesting/puzzling one.

When I click the button I get a "Debug Assertion Failed!" in dbgheap.c on
the expression "_CrtIsValidHeapPointer(pUserData)". When I then break
execution in the debugger and look at the call stack, I see this (snipped
down to what I think are the relevant lines):
msvcr80d.dll!_msize_dbg(void * pUserData=0x1ec966bf, int nBlockUse=2) Line
1473 + 0x30 bytes C++
msvcr80d.dll!_dllonexit_nolock(int (void)* func=0x1e895def, void (void)* * *
pbegin=0x0013eba0, void (void)* * * pend=0x0013eb98) Line 295 + 0xd bytes C
msvcr80d.dll!__dllonexit(int (void)* func=0x1e895def, void (void)* * *
pbegin=0x0013eba0, void (void)* * * pend=0x0013eb98) Line 273 + 0x11 bytes C
ManagedApp.exe!_onexit(int (void)* func=0x00403b50) Line 110 + 0x1b bytes C
ManagedApp.exe!atexit(void (void)* func=0x00403b50) Line 127 + 0x9 bytes C
ManagedApp.exe!NativeSingleton::Instance() Line 16 + 0x32 bytes C++
[Managed to Native Transition]
ManagedApp.exe!ManagedApp::Form1::button1_Click(System::Object^ sender =
0x0013ed28, System::EventArgs^ e = 0x0013ed3c) Line 87 + 0x5 bytes C++

So, as you can see, for some reason as soon as the singleton's Instance()
method is called, the app seems to want to exit (I assume that's why there
are calls to "atexit" and "_onexit". That's as far as my limited debugger
skills can take me. :)
I'll e-mail the project to you and cross my fingers that you can make some
sense out of this.

Even if you can't, thanks very much for your time.
Gordo


"Jeffrey Tan[MSFT]" said:
Hi Gordo,

Can you tell me what error do you get during the crash? Anyway, since you
have a little sample project, please feel free to attach it in the
newsgroup through Outlook Express or send it to me at:
(e-mail address removed)(remove "online."). I think the sample project
will provide more information about this problem.

Thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
J

Jeffrey Tan[MSFT]

Hi Gordo,

Thanks for your sample project. Yes, I can reproduce this error by running
it.

I am not sure of the reason why the compiler will emit a "atexit" calling
after calling the static constructor. However, it seems that this is a
known issue which is reported by some other customer:
"static object in unmanaged code causing crash with Windows Forms"
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?Feedba
ckID=101712

To resolve this problem, you may try to turn on the /clr compiler option in
the "NativeLib" project. To set the /clr compiler option in the Visual
Studio development environment, follow the steps below:
1. Open the project's Property Pages dialog box. For details, see How to:
Open Project Property Pages.
2. Click the Configuration Properties folder.
3. Click the General property page.
4. Modify the Common Language Runtime support property.

After turnning on the /clr option, the compiler will not emit "atexit"
calling. I am also trying to contact some C++/CLI experts internal to
understand why atexit will be generated for non /clr project. I hope they
can share some insight for the root cause. I will post any information here
ASAP. Thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
J

Jeffrey Tan[MSFT]

Hi Gordo,

Sorry for letting you wait.

By further discussing with a developer from VC++ team, he confirmed that
this was a known issue. The main problem here is that the IDE is specific
the entry of ManagedApp as "main". However, using "main" will bypass a lot
of CRT's startup initialization. The fix here is to simply change the
entry point in the IDE. Under ManagedApp -> properties-> link -> advanced,
change "entry point" from "main" to
"?mainCRTStartupStrArray@@$$FYMHP$01AP$AAVString@System@@@Z". That should
re-enable the CRT startup code which initializes the internal CRT variables.

That symbol is really the mangled name for "int __clrcall
mainCRTStartupStrArray(cli::array<class System::String ^ >^)".

D:\repro\onexit>undname
?mainCRTStartupStrArray@@$$FYMHP$01AP$AAVString@System@@@Z
Microsoft (R) C++ Name Undecorator
Copyright (C) Microsoft Corporation. All rights reserved.
Undecoration of :-
"?mainCRTStartupStrArray@@$$FYMHP$01AP$AAVString@System@@@Z" is :- "int
__clrcall mainCRTStartupStrArray(cli::array<class System::String ^ >^)"

This symbol should always exist in the CRT (at least in version 8 and 9) ,
so it should be okay for you specify it as entry point.

Hope it helps.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

Wow! Thanks very very much for tracking that problem down, Jeffrey. I've been
trying various experiments on my own for many weeks, so to me it was a very
short wait. :)

That solution works like a charm, so I'm going to go try it in my production
code right away.

You've definitely made my day. :)

Best regards,
Gordo


"Jeffrey Tan[MSFT]" said:
Hi Gordo,

Sorry for letting you wait.

By further discussing with a developer from VC++ team, he confirmed that
this was a known issue. The main problem here is that the IDE is specific
the entry of ManagedApp as "main". However, using "main" will bypass a lot
of CRT's startup initialization. The fix here is to simply change the
entry point in the IDE. Under ManagedApp -> properties-> link -> advanced,
change "entry point" from "main" to
"?mainCRTStartupStrArray@@$$FYMHP$01AP$AAVString@System@@@Z". That should
re-enable the CRT startup code which initializes the internal CRT variables.

That symbol is really the mangled name for "int __clrcall
mainCRTStartupStrArray(cli::array<class System::String ^ >^)".

D:\repro\onexit>undname
?mainCRTStartupStrArray@@$$FYMHP$01AP$AAVString@System@@@Z
Microsoft (R) C++ Name Undecorator
Copyright (C) Microsoft Corporation. All rights reserved.
Undecoration of :-
"?mainCRTStartupStrArray@@$$FYMHP$01AP$AAVString@System@@@Z" is :- "int
__clrcall mainCRTStartupStrArray(cli::array<class System::String ^ >^)"

This symbol should always exist in the CRT (at least in version 8 and 9) ,
so it should be okay for you specify it as entry point.

Hope it helps.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
J

Jeffrey Tan[MSFT]

Hi Gordo,

Thank you for the kindly word.

FYI: I have further discussed with a senior development lead of VC++ team,
he believes that if we clear up the "entry point" under ManagedApp ->
properties-> link -> advanced, it should pick up the right init function
(i.e. the mainCRTStartupStrArray symbol we talked about). However, further
test shows that this actually does not work.

Finally, he confirmed this as a problem of the VS2005 and will be fixed in
Orcas(next version of VS IDE). Thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top