Hi. I am currently building a small DLL (~20 functions so far) project to sit between a larger DLL and a VB project. I am now at a stage where I want some advice before proceeding (I can fairly easily make changes at this stage, but if I continue it will become impossible.)
At the moment, at the DLL entry point to my project, I am calling just a few functions. One of these functions though, leads to another which leads to another and so on. Basically, the whole program executes without functions returning any result to the caller until right at the end (apart from some small functions to check file existence etc.)
The program flow is something like the following:

    -> Call LoadInternal
        -> Call IndexTest
            -> Call BreakUpCommand
                -> Call ExecuteTest
                   -> Call Execute Command
                       -> Call External DLL

This method of calling seems to have produced a fairly fast program execution time, but I am not sure if projects are generally constructed in this way. I feel it would be better if it was structured in such a way that each method returned its result back to the caller, and have a sort of 'central' function handling all calls.

What are your opinions? I'm sure there are other resolutions I haven't thought of. I'm having difficulty finding anything on the web about best practices on program structure.

Thanks in advance.

I see one big problem. You should not do anything complicated in the DLL entry point function. This is because there are certain intrinsic properties that make the DLL_entry somewhat different from a normal function call. These special things have to do with the OS being able to load the resources for the DLL while doing some initialization. Simply put, the context of the DLL process is not fully formed at the DLL_entry point and this varies from OS to OS (also from version to version).

For example, it is not recommended (or almost forbidden for good practice) to load an external DLL at the entry point. Launching threads of execution is another highly discouraged practice (the OS could deadlock them automatically because of the incomplete context in which they are started)

All you can do really is initialize some static data, create some sync objects and that's about it.

So in your example, you should at least move all this cascade of calls to another function that you require the caller to call immediately after the DLL is loaded and before any other function call to that DLL (or you can use an internal flag to check the initialized status to be able to initialize before executing any other function, but there will be an overhead on each function call that you may or may not want to live with).

When you ask if this is good practice for program structure. That's very vague, you won't find much useful things with such a broad term. At least saying software engineering instead of program structure already increases your chances. Better search for more narrow issues and read about it, good programming practices will emerge and your task as a programmer is to merge them and solve trade-offs between the different challenging aspects of the program.

As for my opinion on it, well there are hardly any universal rules about software design, one size does not fit all. And what you say is too vague, you need to start from the goal and requirements, and then we can discuss the structure. Just giving the structure in broad strokes and asking if it is good does not make much sense.

Here are some of the things you need to ask yourself to know if the software design is good or not:

Are the functionalities of the software easy to modify, delete or add?

Do the different parts of the software have a clear responsibility? With clearly defined boundaries?

How rigid is the structure? If a piece is taken out, does the whole thing crumble? Are there any possible single-point failures?

Who is responsible for what memory? And who uses whose memory? For DLL, this is especially important since dynamically allocated memory can hardly be shared across the DLL boundary (it can, but it essentially requires a few clever tricks and an ABI (Application Binary Interface), which is not a trivial thing to make).

Where are the bottlenecks and where are the CPU loads?

... and many more, but that's a good start (the ones I can think of off the top of my head).

It's good to think long and hard about how to best program the software before heading too deep into the implementation and not being able to make structural changes any more. So make sure you at least can confidently answer the above before you start. Unless of course, it is a very simple project (if less than 5k or 10k lines of code, then it might be a bit of overkill to formally answer all these questions).

This article has been dead for over six months. Start a new discussion instead.