Creating a MFC DLL in Visual Studio - c++

As far as I can tell, Visual Studio 2008 provides two ways of making a MFC DLL:
New Project -> MFC DLL
New Project -> Win32 Project -> select DLL, Export symbols, & MFC
What is the difference? The two methods seem to generate very different starter code. The second methods appears to generate code that I would expect to see for a DLL. Thanks.

The first creates what is called an MFC "Extension DLL". The key distinction here is that this DLL is only available to MFC programs and other DLLs that use MFC. Its public interface may pass MFC types between the DLL and its clients.
The second creates a "Regular DLL" that links to MFC. It can use MFC internally but exposes an MFC-independent interface so non-MFC programs can use it too.
There are more distinctions, which you can read about in the linked pages.

Related

What is Different Between "MFC DLL" and "Console Application DLL"?

What is the difference between creating a MFC DLL from Visual Studio wizard and creating C++ Console Application and changing the configuration type to DLL instead of .exe?
You can surely figure out how to change a console application to dll type, but it's recommended to use the non-MFC DLL project template.
One major difference between a non-MFC and a MFC Extension DLL is that it would allow sharing resources like dialog templates or bitmaps to MFC appliactions by calling
// MFC extension DLL one-time initialization
AfxInitExtensionModule(PROJNAMEDLL, hInstance);
// Insert this DLL into the resource chain
new CDynLinkLibrary(Dll3DLL);
in DllMain(). Other benefits are that you can use MFC (CObject-derived) classes that sit in the dll and that the MFC Extension DLL can share the memory address space with the calling instance, meaning that two apps loading the same extension DLL will only share the code but won't interfere with allocated data.
Note that you need the "shared MFC DLL" project setting to use extension DLLs. Linking MFC statically into your project won't work. So extension DLLs aim at sharing code among different apps that run simultaneously, for example, but only use the code memory once. This way of code reuse was one intention at least when extension DLLs were introduced, but in the real world different apps tend to use different versions (dll hell, side-by-side). Speaking of:
One good use of an extension DLL is to customize an app (branding, localisation) just by installing differend versions of a dll.
Further reading: https://learn.microsoft.com/en-us/cpp/build/extension-dlls
According to Creating an MFC DLL Project it states:
An MFC DLL is a binary file that acts as a shared library of functions that can be used simultaneously by multiple applications. The easiest way to create an MFC DLL project is to use the MFC DLL Wizard.
This article Kinds of DLLs also states:
Using Visual Studio, you can build Win32 DLLs in C or C++ that do not
use the Microsoft Foundation Class (MFC) library. You can create a
non-MFC DLL project with the Win32 Application Wizard.
The MFC library itself is available, in either static link libraries
or in a number of DLLs, with the MFC DLL Wizard. If your DLL is using
MFC, Visual Studio supports three different DLL development scenarios ...
I believe the above explains the difference:
One version of the DLL exposes the MFC library.
One version does not.
That is my understanding.
Other related article: Create C/C++ DLLs in Visual Studio
An MFC DLL is a dynamic library that uses MFC components and the MFC runtime. This means that an MFC dynamic library usually requires the MFC support libraries along with the MFC runtime. To compile an MFC DLL requires the MFC include files and the MFC directives.
When you use the Visual Studio Wizard to create an MFC DLL all the compiler, linker, and other settings and options needed to create an MFC DLL are all generated for you along with an MFC DLL stub.
A Console Application is an application that uses the C++ Runtime from a console window.
When you use the Visual Studio Wizard to create a Console Application all the compiler, linker, and other settings and options to create a Console Application are all generated for you with a Console Application stub which is typically a Hello World type of application with a main() that contains a printf().
The source code for a DLL has required structure for a DLL main entry point that is different from the required structure for a Console Application main entry point. See the Microsoft article DllMain entry point which has this example source code:
BOOL WINAPI DllMain(
HINSTANCE hinstDLL, // handle to DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpReserved ) // reserved
{
// Perform actions based on the reason for calling.
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
// Initialize once for each new process.
// Return FALSE to fail DLL load.
break;
case DLL_THREAD_ATTACH:
// Do thread-specific initialization.
break;
case DLL_THREAD_DETACH:
// Do thread-specific cleanup.
break;
case DLL_PROCESS_DETACH:
// Perform any necessary cleanup.
break;
}
return TRUE; // Successful DLL_PROCESS_ATTACH.
}
So the differences between an MFC DLL and a Console Application involves a number of areas:
the structure of the source code
the include files used in the compile
the libraries used in the link
the options used in the compile
the options used in the link
Changing the configuration type does not modify the source code or include files specified in the source code. Nor does changing the configuration type change all of the necessary compiler and linker options and property settings that need to be changed.
See this Microsoft article, DLLs and Visual C++ run-time library behavior, that discusses the structure of DLLs and their run time behavior which provides an idea as to the differences between an EXE and a DLL.
An Application (executable) is a module that can be run. It contains one entrypoint, the main() (console) or WinMain() (windows GUI) function. A running instance of an executable is called a "process" in Win32.
A DLL is a library, intended for use by other applications. It is loaded at runtime - "dynamically", hence the name. DLLs contain no main entrypoint, instead they "export" functions or even classes and data. Lacking a main entrypoint, DLLs cannot be run stand-alone, instead they are "loaded into a process's (application's) address-space". The process can use their exported items. It is a good way to implement commonly used operations, for example a company's "development environment" or "foundation" - SDKs are typically implemented as DLLs.
MFC is a C++ library containing GUI (and other) classes and functions, largely (but not exclusively) wrapping Win32 objects. An application or DLL can be using the MFC library, or not.
As for your question, creating a console application and then changing it to DLL makes no sense. The Wizard will create a main() function, which you will have to manually remove. And finally you will have what, a normal DLL... You can simply create a DLL from the start, whether it will be using MFC or not.
EDIT:
According to the documentation from Microsoft:
Each process provides the resources needed to execute a program. A process has a virtual address space, executable code, open handles to system objects, a security context, a unique process identifier, environment variables, a priority class, minimum and maximum working set sizes, and at least one thread of execution. Each process is started with a single thread, often called the primary thread, but can create additional threads from any of its threads.
So yes, processes need to contain at least one thread - terminating the primary thread also terminates the process. Furthermore, an executable must contain an entry point, it's what the primary thread will execute and return a value to the system. It's actually impossible to build an executable without a main()/WinMain() function, it will generate Linker Error LNK1561:
entry point must be defined
The linker did not find an entry point, the initial function to call in your executable. By default, the linker looks for a main or wmain function for a console app, a WinMain or wWinMain function for a Windows app, or DllMain for a DLL that requires initialization. You can specify another function by using the /ENTRY linker option.
As for DLLs, the term dynamic "linking" is indeed used by MS, however only to highlight the differences to static linking (what most developers consider linking). It's not linking in the usual way, ie resolving externals, changing symbol names to addresses, performing fixups and the like. A DLL has no unresolved externals and the so called "linking" means just locating exported items from the loaded DLLs (in the case of using an import library they are also assigned to local functions) - the linker is not involved in the procedure. Further information here.
Therefore I don't think that there was something "slightly wrong" in what I had posted above, and certainly not "literally everything".
As for whether my answer should be considered useful or not, I think I was right to suggest not creating an executable and changing it to a dll. An MFC DLL is a DLL "based on" (using) the MFC library - this was clear in my first post. The OP didn't ask about MFC extension DLLs particularly.

How to get ATL support into an existing Windows application

I'm building an application using Qt 5.3.1 in Visual Studio 2012. I also want to use a hardware library which requires me to add a simple ATL object to the project. This can be done by using a Visual Studio wizard. The wizard complains that my project is neither an MFC executable nor an MFC DLL with full ATL support.
My question is: How can I add this support to my application? In the project properties I configured the project to link to the ATL and use the MFC. It did not work. Both statically and dynamically.
If there's another solution in order to add a simple ATL object to the project, please let me know.
The wizard which adds ATL support works on source code of the C++ project, including both checking if the current code is already ATL project, whether the project is okay for adding ATL support to, and code modification per se.
If the wizard "does not like" something in your project it displays an error which basically means that the wizard does know how to safely modify your source code. It does not however mean that adding ATL support is impossible. And enabling an option in project settings is insufficient since source code needs some explicit initialization stuff.
The best you can do to add ATL support without thinking too much about it, is to create a new empty project that matches the project type you currently have, e.g. MFC application. Then take a snapshot of source code, then add ATL support using the wizard. Then compare changes and duplicate them on your real project. The same applies to next step of adding ATL Simple Object using Visual Studio wizard.
Some relevant links (even though the method above looks the easiest to me):
How To Add ATL Support to an MFC EXE
Adding ATL support to existing mfc application
Add automation support to MFC DLL

Debugging into COM C++ code through an .net interop class

Is it possible to step into the COM C++ code that is being used through a .net interop layer created by tlbimp.exe from a C++ program. I see that the symbols for the COM C++ dll is loaded in the Debug->Modules window.
It is possible, but you'll need to set your Visual Studio debugger to mixed mode in project properties. This is located under Project properties->Configuration Properties->Debugging->Debugger Type

How to use ActiveX dll in win32 C++ project visual studio 2010

Background: Vendor has provided me ActiveX Dll, no header files or .tlb file or anything such.
I am using Visual Stdio 2010 and using win32 C++.
The problem I am facing is how to load or reference dll?
I cannot reference the dll through solution explorer because it is unmanaged project.
When I try to use #import, it give me compile error saying XXX.tlb file not found. But I don't have .tlb type file.
The other option I tried was to open the dll with OLE viewer and copy the dll definitions and then paste in .idl extension file I created with Visual Studio. Then I executed midl on the idl file to create .h file but that did not help either. When I try use the classes, its gives me "abstract classes cannot be used or referenced" error.
There are other questions asked on the matter but not straight forward and the answers are not marked as answered or upvoted.
I want to know what are the different methods available to load the ActiveX dll in win32 C++ project in visual studio 2010 and which one should be preferred when? If there is a thread that actually addresses my issue please point me to that.
Thanks
If you are able to see the interface definitions using OLE View it means that the type library is embedded into the dll resources. So if you use #import "YourActiveX.dll" it should work.
You need
Register the COM (Active X) component in windows using regsvr32 : regsvr32 my_dll.dll
Then use COM to interact with the component. This is a good tutorial.

convert "MFC Extension DLL" into "Regular DLL with MFC statically linked" in a hurry

I got the VC++ source code of a dll for a USB device project, which the deadline is close. Right now I have to call this usb dll from another VB program. But the source code is based on the template "MFC Extension DLL", which can´t be called by VB. On the other hand, "Regular DLL with MFC statically linked" can be called by programs written in Visual Basic.
Is there a way, with the least effort of modification of the source code, to be able to call this dll directly from VB?
I tried to modify the project´s configuration properties/Use of MFC to Use MFC in a Static Library. But there is build error.
Now I am modifying the source code based on the new template "Regular DLL with MFC", but there is a lot of problems. For example, I don´t know whether I can use AFX_EXTENSION_MODULE in my new dll code.
Your problem is likely due to not implementing a CWinApp derived object which provides services that the MFC classes in the DLL rely upon. Probably you can just bung one in and it will work.
See here for more information:
http://msdn.microsoft.com/en-US/library/h5f7ck28(v=VS.80).aspx