linking static library into dll - c++

In windows programing,
If you have a static library which is intended to be linked with a dll library where the dll has /SUBSYSTEM:WINDOWS defined, then which of the following marcos should be defined in static library?
_LIB
_WINDOWS
I'm confusing these macros because a static library it self will never show it's own window or console on it's own, so I can't understatnd why do we need to define these macros for static library project?

Just a few points:
It's entirely possible for functions in a static library to create and manipulate UI, either User32 windows or console (I guess Modern UI as well).
Unless you provide special functions for the purpose, the application using your library can't tell what macros were used for library compilation.
Windows headers sometimes will provide defaults if you haven't defined any of a set of macros
(e.g. WINVER)
These macros are only as magic as your code makes them. If you aren't testing them, then defining them is going to have almost no effect.
If your library does conditionally make UI features available, skipping those at compile-time with #if defined(_WINDOWS) has some advantages over run-time enable flags.
In particular, if calls to UI functions are stripped by the preprocessor, the linker won't need to add UI DLLs to the import table. Might make a difference whether your library works on Server Core installs of Windows. At the same time, runtime checks are nice because you only need to compile the library once and distribute one version. Using run-time enable flags and setting the linker to use delay-load might give the best of both worlds.

after fighting with google for houres and various forums and white papers I found out what all that means when using visual studio!
static library:
does not need an /ENTRY or /SUBSYSTEM because the code will be linked into another code.
so the library does not need a console, windnow or entry point
dll:
/SUBSYSTEM should be set to WINDOWS and /ENTRY should not be set, why?
no entry because in visual studio linker automaticaly creates a DllMain entry point.
subsystem of dll should be set to WINDOWS link1 link2
another examle why WINDOWS
exe:
/SUBSYSTEM and /ENTRY should be set explicitly, if not set, linker will again automaticaly set the subsystem AND entry point as noted in the link above.
so to answer my original question, none of the above "stupid" macros must be defined :)

Related

How to reference Windows Runtime classes in a Static Library?

I am new to programming in C++ on Universal Windows Platform and I have a quick question: I created a project of Static Library (Universal Windows) in Visual Studio 2015 but I couldn't use those Windows Runtime classes such as Windows::UI::Core::CoreWindow in that project.
I guess I need to add include directives or references to libraries but I couldn't find information about that. I tried to search MSDN but just found two pages where two headers were mentioned for namespace default and Collections.
Does anyone know how to reference Windows Runtime classes in a Static Library?
You need to build the project with the /ZW option to allow consuming Windows Runtime Extension in a UWP Static Library:
Right click on the project from Solution Explorer
Click Properties
Select C/C++ -> General
Set the "Consume Windows Runtime Extension" to "Yes(/ZW)"
Click OK
After applying this option, references to Windows Runtime Extensions appear under the references of the project and you can use Windows Runtime Classes.
However, you may see a linker warning while building the library:
Debug\pch.obj : warning LNK4264: archiving object file compiled with
/ZW into a static library; note that when authoring Windows Runtime
types it is not recommended to link with a static library that
contains Windows Runtime metadata if you are using a linker released
before VS 2015 Update 2
I tested the scenario and it worked fine in debug mode, however, I'm not sure if it is the best way since the /ZW option is off by default unlike other types of UWP projects.
MSDN:
You can use a native C++ static library in a UWP project, but there
are some restrictions and limitations to be aware of. Start by reading
this topic about static libraries in C++/CX. You can access the native
code in your static library from your UWP app, but it's not
recommended to create public ref types in such a static library. If
you compile a static library with the /ZW option, the librarian
(actually the linker in disguise) warns:
Maybe you should consider wrapping all the code in a Windows Runtime Component or a UWP DLL instead.

c++ What to do if Library makes use of debug version of other library?

A library i'd like to use makes calls to functions like "malloc_dbg" which are defined in libcmtd.lib but not in libcmt.lib (so I get Linker errors in Release mode)
Do I really need to use the debugversion of that lib even in releasemode? or can I somehow use libcmt.lib and libcmtd.lib together, but use libcmtd.lib only for this other library and use the releaseversion for the rest of my application?
Thanks!
Maybe you can implement malloc_dbg yourself and call malloc from there?
But this is just a workaround. The lib you are using should provide you a release version without these calls!
Since your question is
c++ What to do if Library makes use of debug version of other library?
Here's my advice, in this order:
Don't use this library. -- If the library doesn't even provide a proper release version, then it isn't fit for anything.
If you must, and as in your case it appears that the lib requires the static debug version of the runtime lib, then try to create a wrapper around this library so that your project can compile with proper settings.
Compile your project with the debug libraries. If you link statically to the runtime libraries, then you wont have a problem with redistribution and for small stuff it may be acceptable to use this approach.
Since you write in the comment you have this problem with GLUI I assume the fault is with you, not with the library. GLUI is an open source project, so you should be able to compile the lib (even an old version) with the appropriate settings for your environment.

How do I create a Win32 DLL without a dependency on the C runtime

Using Visual Studio 2008 and its C/C++ compiler, how do I create a Win32 DLL that is dependent only on other Windows DLLs, and has no dependency on the Microsoft C runtime?
I have some C code I want to place in a DLL that is entirely computation, and makes almost no use of C library functions.
For those it does use (eg memcpy), I'm happy to rework the code to use the Win32 API equivalents (eg CopyMemory).
Use the /NODEFAULTLIB linker option and (of course) make sure you have no actual dependencies on the runtime. You'll also have to specify & define your own entry point for the DLL using the /ENTRY linker option or alternatively have your own entry point function that matches the name expected by the compiler/linker (for a dll, that's _DllMainCRTStartup).
Matt Pietrek's article from way back when on LIBCTINY will probably have all the information you need:
http://msdn.microsoft.com/en-us/library/bb985746.aspx
for "Debug" mode try this:
Go to Project\[Projectname] Properties...
Open Configuration Properties
Open C/C++
Open Code Generation
For Runtime Library Select Multi-threaded Debug (/MTd) instead of Multi-threaded Debug DLL (/MDd)
for "Release" mode, do same steps except that selecting Multi-threaded (/MT) in the last step.
This causes any C Runtime function that used in your program to be statically-linked to your binary file.
You may have more dependencies on the CRT than you think. It tears down resources like thread local storage, and global class initializers are run by the CRT before main().
Consider linking with a static CRT, as someone said, and if you really really don't want to, use /NODEFAULTLIB and /ENTRY as someone else said.
Oh, and instead of reworking memcpy, consider using the super-fast compiler intrinsic for it. You can turn on intrinsics with /Oi.
The /NODEFAULTLIB linker flag is not actually the proper flag. It will ignore all default libs, including others like uuid.lib.
What you want is the /Zl compiler option, "omit default library name in .OBJ".
You'd have to make sure none of the Win32 DLLs you use need the C runtime as well or else you back at square one. Compiling your DLL statically won't matter if one of the Win32 DLLs depends on the C runtime.
The only way I can see this working is to statically link ALL your dependent DLLs (if that is even feasible) into your DLL. This of course means you would have to recompile to take advantage of any DLL updates.
Some Windows libraries depend on the C runtime (ODBC32.DLL, for example)
so I think you are on a hiding to nothing here. Why would you want to do this, anyway?
Compile it with static microsoft lib.

Why is runtime library a compiler option rather than a linker option?

I'm trying to build a C/C++ static library using visual studio 2005. Since the selection of the runtime library is a compile option, I am forced to build four variations of my library, one for each variation of the runtime library:
/MT - static runtime library
/MD - DLL runtime library
/MTd - debug static runtime library
/MDd - debug DLL runtime library
These are compiler options, not linker options. Coming from a Linux background, this seems strange. Do the different runtime libraries have different calling conventions or something? Why can't the different runtime libraries be resolved at link time, i.e. when I link the application which uses my static library?
These options may add defines (__DLL and __DEBUG for example) that are used in the runtime library header files. One common thing to do is to add __declspec(dllimport) to function declarations when linked dynamically.
The compiler also seems to use these to assist the linker in linking to the correct libraries. This is explained in the MSDN.
One side effect of the C preprocessor definitions like _DLL and _DEBUG that zdan mentioned:
Some data structures (such as STL containers and iterators) may be sized differently in the debug runtime, possibly due to features such as _HAS_ITERATOR_DEBUGGING and _SECURE_SCL. You must compile your code with structure definitions that are binary-compatible with the library you're linking to.
If you mix and match object files that were compiled against different runtime libraries, you will get linker warnings such as the following:
warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs
The compiler needs to know if you are generating single threaded or multi-threaded code. By default the compiler generates thread safe code (multi-threaded). You have to tell it if you want single thread code.If you change the default the compiler changes the default run-time library (you can always override this in the linker command options, just be sure that the library you pick has the same code structure as your object files: single-threaded static, multi-threaded static or multi-threaded DLL). Note that there is no single-threaded DLL option (by definition the run-time library DLL will have been built as thread safe as it is shared by multiple apps).
If you ignore the static runtime then you get the same options as Linux.
I know static runtime can be usful but I have never actually needed it. Also it leads to potential problems dealing with allocation/deallocation of memory and as a result I find it easier to just to use the DLL runtime.
Having Release/Debug version is the same as Linux/Unix though.
Though for effeciency I reasons I alos build a single thread and multi thread versions of libraries.
I believe the reason behind this is that SEH (structured exception handler) code will be generated differently depending on which runtime library you link against.
There is different machine code generated for DLL's and static libraries.
And on Linux you have to do the same, the compiler flag is called -fPIC if you want to build a shared library. Otherwise on AMD64 and SPARC (and maybe others) it will crash. On i386 architecture the linker is clever enough and does not share the library in memory so it won't crash.

Is it possible to build a DLL in C++ that has no dependencies?

I would like to deploy a very simple DLL with my C# application, but any DLL that I build in Visual Studio 2008 seems to have a dependency on "Microsoft.VC90.CRT". Is it possible to build a DLL using VS2008 without this dependency? How can I tell what is causing the dependency?
I'm not sure about the latest VC++ versions, but previously you could tell the linker to link with a static version of the MSVCRT runtime library instead of the dynamic (DLL) version. It's possible this option still exists.
According to this MSDN page, static libraries are still available.
Go to project properties, configuration properties, C/C++, Code generation, Runtime Library.
Select Multithreaded Debug for the debug configuration, and Multithreaded for the release config. (Not sure if the names are all the same in VS2008, but should be "somewhere around there". Can update tomorrow with VS2008-specific differences)
Also, as wbic16 suggested, use dependency walker to identify other static dependencies.
If you're absolutely sure you don't have any dependencies on the C runtime, then you can avoid linking against it by enabling the "Ignore All Default Libraries" (/NODEFAULTLIB) flag under the Linker -> Input project options page. You may also have to disable basic runtime checks (set "Basic Runtime Checks" to Default under C/C++ -> Code Generation), and you might also have to remove the entry point (set "No Entry Point" to "Yes (/NOENTRY)" under Linker -> Advanced).
See also http://support.microsoft.com/kb/814472, it has some good information about building DLLs for Managed Extensions for C++.
Edit: Notice that running without C runtime also means you don't have easy memory allocation function like malloc() and new.
Give this tool a shot: http://www.dependencywalker.com/. It will let you walk through your dependencies on a given exe or dll.
With a bit of work, libCTiny still works as a replacement for the default lib. This kind of library makes /NODEFAULTLIB usable.
To answer your second question, with the /VERBOSE linker switch the linker will tell you which symbols are taken from which library.
Make sure your building every thing in release as often in debug, the dll gets linked with special debug dlls that are not normally shipped with windows and will cause dependency issues.