C runtime library woes in Managed C++

G

Gerhard Menzl

When creating a Managed C++ DLL using the Visual Studio 7.1 Solution
Explorer (by selecting Add New Project and then either choosing Class
Library (.NET) or Windows Control Library (.NET)), the IDE sets the
/MT(d) compiler switch (statically linked multithreaded C runtime
library) by default. This is fine with me, as it relieves me from having
to redistribute MSVCR71(D).DLL with my application.

However, as soon as a single runtime library function is used in my
DLL's code, the linker complains:

error LNK2019: unresolved external symbol _main referenced in
function _mainCRTStartup

main? In a DLL? Sure enough, the error goes away when I change /MT(d) to
/MD(d), but then I have to redistribute MSVCR71(D).DLL and risk all
kinds of version troubles.

I must say that information on this issue both on MSDN and the entire
Internet is rather poor. There is no indication that DLLs *require*
/MD(d) (my understanding is that the D refers to the runtime library,
not the client assembly, being a DLL), yet building them with /MT(d)
doesn't work. But why does the IDE set the latter option by default? Do
I really have to add a dummy main() function to my DLL when using
/MT(d)? Or have I missed something?
 
G

Gerhard Menzl

Nikola said:
The "The Managed C++ Wrapper Library" chapter of this paper
http://www.codeguru.com/Cpp/Cpp/cpp_managed/interop/article.php/c6867/
contains instructions that you may find useful. Give it a try and let me
know if that solves your problem.

Thank you very much for the link. This article, and the article
"Converting Managed Extensions for C++ Projects from Pure Intermediate
Language to Mixed Mode" in the Visual C++ documentation which I
discovered after browsing the former, shed some light on the matter, but
they do not really provide a satisfactory answer. The compiler switches
/MT(d), /MD(d) etc. aren't even mentioned; it simply says "use
msvcrt.lib" (which is implicit with /MD), and it doesn't mention the
debug version.

The mentioned articles also suggest adding __DllMainCRTStartup@12 to the
Force Symbol References property, but the linker complains about the
unresolved external symbol _main. How does that fit together?

In the meantime, I have - hopefully - solved my problem by compiling all
assemblies using /MD(d) and deploying mscvr71(d).dll and msvcp71(d).dll.

Why is this important piece of information so cleverly hidden? Why is
there no mixed mode/pure MSIL switch to be found in a project's
properties or in the New Project dialog? There must be millions of lines
of C and C++ legacy code out there that people want to integrate into
..NET applications. This is not an obscure corner case.
 
N

Nikola Dudar [MSFT]

Gerhard,



Managed DLL built with /MT in VS2003 is subject to loader deadlock issue.
The linker throws these error messages to ensure that users are aware of the
potential deadlock. The paper, I have sent a link to in my previous post,
is a short summary of this paper http://support.microsoft.com/?id=814472,
which goes into deep details of this problem, proposes workarounds and has
links to other useful papers.



FYI, in VS2005 Beta1, the CRT design has been changed to overcome the loader
deadlock issue. The CRT provides two initialization routines - native (main,
dllmain) entry points (as they were before), in which managed code should
not be called, and managed module constructor, which properly initialize
managed binaries. This ensures that no calls to managed code are done from
inside native initialization routines, when OS loader lock is held. There is
also a better diagnostic which helps users to identify the problem. See
http://msdn.microsoft.com/visualc/default.aspx?pull=/library/en-us/dnvs05/html/debgb1ldlk.asp
for a detailed summary.



Also in Beta1 user can only link managed binaries with /MD[d] mostly because
of the same reasons. That is why I would say that you should build your app
with /MD. That not only helps to overcome the loader deadlock but also makes
your code ready for VS2005. However, it is always up you as an owner of the
app to know what design is better. :)



Thanks,
--

Nikola Dudar
Visual C++; // Program Manager
This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Gerhard Menzl

Nikola said:
Managed DLL built with /MT in VS2003 is subject to loader deadlock issue.
The linker throws these error messages to ensure that users are aware of the
potential deadlock. The paper, I have sent a link to in my previous post,
is a short summary of this paper http://support.microsoft.com/?id=814472,
which goes into deep details of this problem, proposes workarounds and has
links to other useful papers.

Also in Beta1 user can only link managed binaries with /MD[d] mostly because
of the same reasons. That is why I would say that you should build your app
with /MD. That not only helps to overcome the loader deadlock but also makes
your code ready for VS2005. However, it is always up you as an owner of the
app to know what design is better. :)

Does that mean that using /MD spares me from the contortions described
in the article cited above?
 
N

Nikola Dudar [MSFT]

Yes, inVS2003 it is easier to build DLL when using /MD.
--
Nikola Dudar
Visual C++; // Program Manager
This posting is provided "AS IS" with no warranties, and confers no rights.



Gerhard Menzl said:
Nikola said:
Managed DLL built with /MT in VS2003 is subject to loader deadlock issue.
The linker throws these error messages to ensure that users are aware of
the potential deadlock. The paper, I have sent a link to in my previous
post, is a short summary of this paper
http://support.microsoft.com/?id=814472, which goes into deep details of
this problem, proposes workarounds and has links to other useful papers.

Also in Beta1 user can only link managed binaries with /MD[d] mostly
because of the same reasons. That is why I would say that you should
build your app with /MD. That not only helps to overcome the loader
deadlock but also makes your code ready for VS2005. However, it is always
up you as an owner of the app to know what design is better. :)

Does that mean that using /MD spares me from the contortions described in
the article cited above?

--
Gerhard Menzl

Humans may reply by replacing the obviously faked part of my e-mail
address with "kapsch".
 

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