Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / Managed C++ / July 2006

Tip: Looking for answers? Try searching our database.

Singleton in native library with C++/CLI

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Adrian - 11 Jul 2006 22:59 GMT
Hi,
I have a large unmanaged static C++ library which I've wrapped using a small
C++/CLR DLL.  This is called from a C# client application.

The static library has a singleton, however it appears that it is being
instantiated twice.  The first instantiation is down to me calling
singleton.instance() in the C++/CLR DLL, the second instantiation is down to
the library internally calling singleton.instance().

I'm relatively new to C++/CLR, is this expected behaviour and is there
anything I can do to work around this?

Thanks,
Adrian
Russell Hind - 12 Jul 2006 06:01 GMT
> Hi,
> I have a large unmanaged static C++ library which I've wrapped using a small
[quoted text clipped - 7 lines]
> I'm relatively new to C++/CLR, is this expected behaviour and is there
> anything I can do to work around this?

I've just converted a small DLL from C++Builder to a C++/CLI DLL in
vs2005 that uses singletons with no real problems.  It isn't
instantiated twice for me.  The only issue I had was with cleanup.  To
destroy the singleton we use std::atexit to register a cleanup func but
in C++/CLI, you have to call _onexit_m (found this because of crashes at
shutdown).

Cheers

Russell
Adrian - 13 Jul 2006 20:55 GMT
> I've just converted a small DLL from C++Builder to a C++/CLI DLL in vs2005
> that uses singletons with no real problems.  It isn't instantiated twice
> for me.  The only issue I had was with cleanup.  To destroy the singleton
> we use std::atexit to register a cleanup func but in C++/CLI, you have to
> call _onexit_m (found this because of crashes at shutdown).

Hi,
Unfortunately my situation is more complex than that - I'm calling an
existing static C++ class library which is for all purposes too complex to
convert to C++/CLI from a C++/CLI program.

I've managed to reproduce the problem in a small VS2005 project - I've
uploaded it at http://www.aonaware.eclipse.co.uk/temp/SingletonTest.zip if
anyone has the time to look.  You can see / debug the constructor of the
singleton being called twice.  I think it may have something to do with the
template base class for the singleton but I'm not sure...

Thanks,
Adrian
Tamas Demjen - 13 Jul 2006 23:57 GMT
> I've managed to reproduce the problem in a small VS2005 project - I've
> uploaded it at http://www.aonaware.eclipse.co.uk/temp/SingletonTest.zip if
> anyone has the time to look.  You can see / debug the constructor of the
> singleton being called twice.  I think it may have something to do with the
> template base class for the singleton but I'm not sure...

That's interesting. I tried your code, and the constructor is really
called twice.

However, I don't understand why your Settings::internalFunction is
static. Since Settings is a singleton class, it's not really needed to
make any of its members static. I modified your code this way:

Settings.hpp:
void internalFunction();

Settings.cpp:
void Settings::internalFunction()
{
   getProperty();
}

Wrapper.h:
static void doSomething() {
   Settings::instance().internalFunction();
}

And now it works fine, the constructor is only called once.

I also took a look at your project settings, and noticed that your
SingletonTest.lib is NOT compiled with the /clr. Mixing managed and
unmanaged code can somtimes bring up very subtle problems, as you can
read it at Marcus Heege's blog:

http://www.heege.net/blog/default.aspx#ad5e2c3da-ff4d-40bc-bea9-9da8ec9e091e

Read "Avoid native code in managed object files (".obj" files)"

I'm not sure if your problem is related to this in any way, but guess
what. I recompiled your SingletonTest.lib with the /clr settings, then
the rebuilt the dll and the C# code, and the problem disappeared.

So I gave you 2 different workarounds for your problem.

I'm not sure if this glitch is considered a compiler bug, or simply bad
practice, but it certainly looks serious to me.

Tom
Russell Hind - 14 Jul 2006 09:00 GMT
> Read "Avoid native code in managed object files (".obj" files)"
>
[quoted text clipped - 6 lines]
> I'm not sure if this glitch is considered a compiler bug, or simply bad
> practice, but it certainly looks serious to me.

Could it be that the singleton is initialised once for native code and
once from managed code?  Perhaps there is an issue with statics called
from both?

Cheers

Russell
Tamas Demjen - 14 Jul 2006 18:13 GMT
> Could it be that the singleton is initialised once for native code and
> once from managed code?

Exactly. Thanks for the hint -- now I see that the same include file was
compiled into managed code in one project, and into unmanaged code in
the another project. Then the two object files were linked together,
which caused one function call to use a different singleton than the
other function call.

Tom
Tamas Demjen - 14 Jul 2006 18:10 GMT
> I've managed to reproduce the problem in a small VS2005 project

I know exactly what's wrong with your project. When you compile a
project with /clr, the default is #pragma managed. When you compile it
without /clr, the default is #pragma unmanaged. Now you can mix the two
things, but you have to make sure that the *same* piece of header file
is compiled with the same settings.

In your project, when you #include "Settings.hpp" and "Singleton.hpp",
the same declaration is compiled as #pragma unmanged in the unmanaged
LIB, and with #pragma managed in the managed DLL. The two things are
*not* byte compatible! You're compiling the same piece of code with
completely incompatible ways, and then link to two things together.

The simplest fix to your problem is to go to Wrapper\Stdafx.h, and
modify it to the following:

#pragma unmanaged
#include "Settings.hpp"
#pragma managed

Please forget my previous message that I sent yesterday. It's not that
it's not correct, but it doesn't show your real problem. Your real
problem is explained in this message.

Just to clarify things. You are not normally required to compile every
native-style class with #pragam unmanaged. You can very easily compile
ISO C++ classes into managed code:

#pragma managed
class NativeClass { }; // generates managed code

However, you're including a non-/clr header file to your /clr project.
You really have to make sure that the compiler settings are matching.

This is the same kind of mistake as putting #ifdef _DEBUG into your
header file, and linking your library project without _DEBUG defined,
but your main application with _DEBUG defined. When the same header file
is compiled with different compiler options, you're calling for trouble.
You can easily lose byte compatibility. This is exactly what happened
with your project -- Singleton.hpp was compiled with one compiler
setting here, and another compiler setting there, and then the two
things were linked together.

Now I can tell for sure that this was definitely not the compiler's
fault. This is something you have to watch carefully when mixing
unmanaged and managed units.

Hope this helps.

Tom
Adrian - 15 Jul 2006 11:22 GMT
> Please forget my previous message that I sent yesterday. It's not that
> it's not correct, but it doesn't show your real problem. Your real problem
> is explained in this message.

Excellent - thank you very much for this post - it explains my problem
exactly.

Thanks again.

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.