Is this a good way to use dlls? (C++?) - c++

I have a system that runs like this:
main.exe runs sub.exe runs sub2.exe
and etc. and etc...
Well, would it be any faster of more efficient to change sub and sub2 to dlls?
And if it would, could someone point me in the right direction for making them dlls without changing a lot of the code?

DLL really are executables too. They comply to the PE standard which covers multiple common file extensions for windows, like .exe, .dll, .ocx...
When you start 2 executables they each get their own address space, their own memory and such. However when you load an executable and a dll, the dll is loaded into the process space of the executable so they share a lot of things.
Now depending on how your 3 executables communicate together (if they even communicate together), you might have to rewrite some code. Basically the general approach to having dlls is to simply call the dll function from inside your program. This is usually much simpler than interprocess communication

DLLs would definitely be faster than separate executables. But keeping them separate allows more flexibility and reuse (think Unix shell scripting).
This seems to be a good DLL tutorial for Win32.
As for not changing code much, I'm assuming you are just passing information to theses subs with command line arguments. In that case, just rename the main functions, export them from the DLL, and call these renamed "main" functions from the main program.

If your program (main.exe) is merely starting programs that really have nothing to with it, keep doing what you're doing. If sub.exe and sub2.exe contain functionality that main.exe would benefit from, convert them to dlls, so main.exe can call functions in them.
When it comes to efficiency, it depends on how large sub.exe and sub2.exe are. Remember that loading a dll also implies overhead.

There are several factors to take into consideration. For starters, how often do you run that sequence, and how long is the job executed by the other executables? If you do not call them very often, and the job they execute is not very short, the load time itself becomes insignificant. In that case, I'd say go with whatever fits the other needs. If, OTOH, you do call them quite a lot, I'd say make them DLLs. Load them once, and from that point onward every call is as fast as a call to a local function.
As for converting an exe to a dll - it should not be very complicated, but there are some points when working with dlls that require special care: using dllmain for initialization has some limitations a regular main doesn't have (synchronization issues); you'll have to keep in mind a dll shares the address space with the exe; CRT versions discrepencies might cause you grief and so on.

That depends on how often they are run. That if, is the tear-up/tear-down of processes is a significant cost.

Wouldn't it be safer to convert them to dll's to prevent the user from accidentally running sub1 or sub2 without main starting them?

Related

Using exe or DLL for calling program from another program

I have a big program A that at some point calls my (big) program B. Program B is called only once in Program A. At the moment Program B is an executable Program (B.exe - compiled C++-Code).
Somebody proposed using a DLL of Program B instead of using the executable.
Are there any advantages in using a DLL ( like security, size, etc.)
Is it easy to create a DLL from my source-code ( I use Qt creator)
Are there any advantages in using a dll ( like security, size, etc)
No. As a matter of fact, if you're looking at things like security, size, etc. using a DLL makes things worse. When you load a DLL, everything happens inside the loading process' address space. So any bug inside the DLL directly affects the rest of the program. A crash in the DLL code, will crash the whole program.
Is it easy to create a dll from my source-code ( I use Qt creator)
Yes it is. But to me it seems there's hardly any benefit for your particular use case. As a matter of fact, for rarely used code paths I'd rather strongly encourage putting it into a separate process (i.e. link it into a .EXE).
BTW: .dll and .exe are exactly the same. You can load a .exe as if it were a DLL; give it a DllMain and you can use it either way! Of course loading a EXE with LoadLibrary won't make it run in a separate process and rather import all the bugs into your main program.

Can changes to a dll be made, while keeping compatibility with pre-compiled executables?

We have a lot of executables that reference one of our dlls. We found a bug in one of our dlls and don't want to have to re-compile and redistribute all of our executables to fix it.
My understanding is that dlls will keep their compatibility with their executables so long as you don't change anything in the header file. So no new class members, no new functions, etc... but a change to the logic within a function should be fine. Is this correct? If it is compiler specific, please let me know, as this may be an issue.
Your understanding is correct. So long as you change the logic but not the interface then you will not run into compatibility issues.
Where you have to be careful is if the interface to the DLL is more than just the function signatures. For example if the original DLL accepted an int parameter but the new DLL enforced a constraint that the value of this parameter must be positive, say, then you would break old programs.
This will work. As long as the interface to the DLL remains the same, older executables can load it and use it just fine. That being said, you're starting down a very dangerous road. As time goes by and you patch more and more DLLs, you may start to see strange behaviour on customer installations that is virtually impossible to diagnose. This arises from unexpected interactions between different versions of your various components. Historically, this problem was known as DLL hell.
In my opinion, it is a much better idea to rebuild, retest, and redistribute the entire application. I would even go further and suggest that you use application manifests to ensure that your executables can only work with specific versions of your DLLs. It may seem like a lot of work now, but it can really save you a lot of headaches in the future.
It depends
in theory yes, if you load the dll with with LoadLibrary and haven't changed the interface you should be fine.
If you OTOH link with the .dll file using some .lib stub there is no guarantee it will work.
That is one of the reasons why COM was invented.

Catching calls from a program in runtime and mapping them to other calls

A program usually depends on several libraries and might sometimes depend on other programs as well. I look at projects like Wine and think how do they figure out what calls a program is making?
In a Linux environment, what are the approaches used to know what calls an executable is making in runtime in order to catch and map them to other calls?
Any code snippets or references to resources for extra reading is greatly appreciated :)
On Linux you're looking for the LD_PRELOAD environment variable. This will load your libraries before any requested by the program. If you provide a function definition that matches one loaded by the target program then your version will be called instead.
You can't really detect what functions a program is calling however. You can however get all the functions in a shared library and implement all of those. You aren't really catching the functions, you are simply reimplementing them.
Projects like Wine do this in some cases, but not in all. They also rewrite some of the dynamic libraries. So when a Win32 loads some DLL it is actually loading the Wine version and not the native version. This is essentially the same concept of replacing the functions with your own.
Lookup LD_PRELOAD for more information.

Distributing DLLs Inside an EXE (C++)

How can I include my programs dependency DLLs inside the EXE file (so I only have to distribute that one file)? I am using C++ so I can't use ILMerge like I usually do for C#, but is there an easier way to automatically do this in Visual Studio?
I know this is possible (thats why installers work), I just need some help being pointed to the best way to this.
Thank you for your time.
There are many problems with this approach. For one example, see this post from REAL Software. Their “REALbasic” product used to do this and had problems including:
When writing the DLLs out at run-time, it would trigger anti-virus warnings.
Problems with machines where the user doesn’t have write permissions or is low on disk space.
Their attempt to fix the problem caused more problems, including crashes. Eventually they relented and now distribute DLLs side-by-side with apps.
If you really need a single-EXE deployment, and can’t use an installer for some reason, the reliable way is to static-link all dependencies. This assumes that you have the correct .libs (and not just .libs that link in the DLL).
There exist two options, both of which are far from ideal:
write a temporary file somewhere
load the DLL to memory "by hand", i.e. create a memory block, put DLL image to memory, then process relocations and external references.
The downside of the first approach is described above by Nate. Second approach is possible, but is complicated (requires deep knowledge of certain low-level things) and doesn't allow the DLL code to access DLL resources (this is obvious - there's no image of the DLL so the OS doesn't know where to take resources).
One more option usable in some scenarios: create a virtual disk whose contents are stored in your EXE file resources, and load the DLL from there. This is possible using our SolFS product (OS edition), but creation of the virtual disk itself requires use of kernel-mode drivers which must be written to disk before use.
Most installers use a zip file (or something similar) to hold whatever files are needed. When you run the installer, it decompresses the data and puts the individual files where needed (and typically adds registry entries, registers any COM controls it installed, etc.)

Is it bad practice to have an application which ships with lots of DLL's?

Is it better to have lots of DLL dependencies or better to static link as mich as possible?
Thanks
No, it is not bad practice to ship with lots of DLLs; it is bad practice, though, to put them in %System32%. Actually, it is usually good to use DLLs instead of statically linking; for one thing, you can easily swap out just the DLL that you need to update, rather than having to replace the entire binary, and for another, if your program eventually needs multiple executables that work together, you only pay for one copy of the DLL code (whereas, with static linking, you would end up duplicating the code that was common).
Having static link gives your app a large memory footprint, therefore having DLL's is better from that POV i.e. you only load what you need. Nowadays installations are normally done by an installer so it doesn't matter if you have lots of DLL's.
I don't think it's a bad practice. Look at Office or Adobe or any large-scale application. They end up with lots of DLLs -- because they otherwise would have to pack everything into a 100M+ exe.
Break things into DLL when you don't absolutely need them.
Generally speaking it is not a bad practice. It is better to split the code of a program into separated dynamic libraries, especially if the functions provided are used from more than one executable.
That doesn't mean that every program should have its code split in more dynamic libraries; for simple utilities, that is not probably needed.
As mentioned by others, lots of DLLs is not a bad practice. Put some thought into what to put in each one. I like to keep the DLLs as 'tiny-island-ish' as I can. If these will be distributed, I like to have a specific naming convention that reflects the product and/or company name and/or initials of some sort.
Just wanted to add another observation from other programs that use many dynamically loaded DLLs. For example, the GIMP and its plug-ins. The way you load your DLLs will affect your client's perceived application speed, if that's a factor among the other very good ones (updates, reuse, etc.). I'm sure there's some overhead for the OS to load a DLL and you might run into process limits (like open file handles). Having very many very small DLLs might not be as desired as "smaller than that" number of "larger than that"-sized DLLs.