Recommendations for building a windows dll - c++

I am trying to create a Windows dll out of a few visual c++ projects that I am working on. My larger goal is to create a dll that can be linked by clients without worrying(too much) about the nuances of how my dll was compiled.
I would like to understand better if there are a few basic compiler flags that I should use that is broadly acceptable.
Are there generally accepted procedures for how struct should be written if I need to export out of the Dll. Especially something that wouldn't be too sensitive to packing alignments. The client might have a 4byte packing, or something else for their own project. How to make sure that doesn't affect if my headers are 8byte aligned.
Does creating a win32 dll or MFC dll matter.
I did structure my project such that classes are exported based on the ideas mentioned here:
http://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-from-a-DLL

Some point witch crosses my mind.
Do not use stl objects in public method signatures or structs.
If possible use only simple data types in your signatures.
If you have to export some structs, define the packing in the header.

Have a look at the Best Practices for Creating DLLs, this is basic stuff but often ignored issues that can lead to very ugly side effects.

Related

Advantage of wrapping classes in DLLs

I've just finished a phase in my project where I wrote a small infrastructure to carry out a certain task, made of a core class with several auxiliary classes.
The C++'ness is quite basic - single inheritance, some STL containers, that's it.
No threads - client runs the show.
What I would like to do now is wrap it all up in a DLL, version it, and use
it as a standalone unit. I'd like that seperation in order to track changes and
development better, and perhaps for other projects as well.
As I don't have experience with classes in DLLs, I would like to hear yours:
What's your approach to this problem?
Specifically:
Is it worth the trouble?
Do you do that often or not at all?
What about compatibiliy issues (like clients compiled using a different compiler)?
I'm not really asking for a debate (though that's the probable outcome), but rather an advice from experience.
Thanks for your time.
I find it hard to see any benefit with this. I can see plenty of problems:
No type checking across a DLL boundary. Any version mismatches will result in runtime failures, harder to detect than compile time failures.
Extra deployment headaches. You may be tempted to update some but not all modules and so deal with complex dependencies.
All clients that want to use these DLLs must use the same compiler.
Only make this change if you can identify benefits that outweigh the negatives.
C++ code is not binary compatible between compilers, it's generally no use creating DLLs exposing C++ classes that aren't built as part of the project that uses them.
If you want to create a Windows DLL with a well-defined object-oriented interface that the rest of the world can use, make it a COM inproc server.

Preparing a library for plugin support

I searched for this particular question but could not come up with any results, neither here nor on-line in general (maybe because it is a little harder to phrase for me). If it has already been asked, please point me in the right direction.
I am at a point where I would like my libraries/software to be pluggable. I see all these various libraries and systems where plugins are used extensively and the authors boastfully point out (in a good way!) that their software has plugin support.
So my question is, where do I start? Are there any books/on-line-resources that break the ice and may guide one on the do's and dont's of making your library pluggable, define best practices etc.?
You have to understand some things before starting :
There is no support for modules (static or dynamic) in standard C++. Nope. Not yet. Maybe in 2015.
Dlls (or .so on unix-like systems) are dynamically loaded libraries that are compiler/os dependant. So it's a pragmatic solution that fill the need.
So, you'll have to use shared libraries (whatever the file extension, it's the keyword for searches about this subject) as plugin binaries. If your plugin should contain more than runtime code, like graphic resources, you can include your graphic resources in the binary, or have a file format or compressed archibe that contain the binary file.
Whatever the way you setup your plugin files, in C++ the problem is about the interface.
Depending on wich compiler you use, you'll have different ways to "tag" functions or classes as exported/imported (meaning your plugin source code export the code and the user of the plugin should import the code).
Setup clean and clear interface in C++ for the modules, with no templates (because they are compiler and compiler configuration dependant). Those interfaces should be function declarations and class declarations with no inline code and marked exported/imported.
Now, once you've got this, you can use OS-specific API to load/unload dynamic library binaries while the application is running. Once it's done, you can get pointers to functions, again using the OS-specific API. I let you search for it.
Now, there are libraries that provide ways to abstract this in a cross-platform way. I didn't use them yet and they are known to be unperfect because of lack of definitions in the C++ standard, but they could be useful if you're planning to have your application cross-platform:
boost::extension : it's not yet a boost library, nor even proposed yet, and it's developpement is in pause (until some new standard C++ implementations are done) so it might be a bad idea but a lot of people say they use it with success.
POCO libraries have a library for shared libraries that would be the equivalent of boost::extension. Again lot of people say it's useful so I guess it's good enough to be used.
The other alternative, that is easy to setup if you don't need to support tons of target platforms, is to just write some wrapper code around OS-Specific APIs. That's what I did before knowing about boost::extension for example.

What's the simplest way to write portable dynamically loadable libraries in C++?

I'm working on a project which has multiple similar code paths which I'd like to separate from the main project into plugins. The project must remain cross-platform compatible, and all of the dynamic library loading APIs I've looked into are platform specific.
What's the simplest way to create a dynamic library loading system which can be compiled and run on multiple operating systems without extra modification of the code? Ideally, I'd like to write one plugin, and have it work on all the operating systems the project supports.
Thanks.
You will have to use platform dependent code for the loading system. It's different loading a DLL on Windows than loading a shared object in Unix. But, with a couple of #ifdef you will be able to have mostly the same code base in the loader.
Having said that, I think you can make your plugins platform independent. Of course, you will have to compile it for every platform, but the code will be 99% the same.
Dynamic library loading an Windows and Unix/Linux works with 3 functions. A pair of functions to load/unload the libraries, and another function to get the address of a function in the library. You can easily write a wrapper around these three functions to provide cross operating systems suppport.
Ideally, I'd like to write one plugin, and have it work on all the operating systems the project supports.
Few things from top of my head:
Avoid static objects in the dynamic libraries. Provision proper initialization methods/functions to allocate the objects. The issues which occur during library being loaded by the OS (this is when the c'tors for static objects are called) are very hard to debug - next only to the multi-threading issues.
Interface headers may not contain code. No inline methods, no preprocessor defines. That is to avoid tainting application with the code from particular version of library, making it impossible to replace the library at later time.
Interface headers may not contain implementation classes themselves - only abstract classes and factory functions. Similar to the previous point - to avoid application depend on the particular version of the classes. Factories are needed as a way for user application to instantiate the concrete implementation classes.
When introducing new version of an interface, to keep things somehow backward compatible, do not modify existing abstract class - create new abstract class inherited from it and add new methods there. Change factory to return the new version. (Recall MS' IInterface, IInterface2, IInterface3 and so on.) In the implementation, use newer version of the abstract class. That by polymorphism would make the implementation backward compatible with the older interface versions. (That obviously calls for periodic interface maintenance and clean-ups - to remove the old cruft.)
Take a look at the boost.extension library, it is not really part of boost, but you can find it in the sandbox. It is kind of frozen also, but overall the library is stable and easy to use.

Unmanaged C++: How to dynamically load code?

Our industry is in high-performance distributed parallel computing. We have an unmanaged C++ application being developed using Visual Studio 2008.
Our application (more like a framework) is supposed to be able to dynamically load code (algorithms) developed by 3rd parties (there can be many dlls) that conforms to our interface specification, and calls the loaded code to get some results.
Think of it like you want to call a sin(x) function, but there are many different implementations of sin(x) that you could use.
I have a few questions as I'm very new to this area of dynamically loading code:
Is dll (dynamic-link library) the answer to this type of requirement?
If the 3rd-party used a different type of IDE to create the dll compared to mine (say Eclipse CDT, C++Builder, Visual C++ 6.0, etc), would the dll still work with my application?
Our application is supposed to work cross-platform as well (should be able to run on Linux), would using QLibrary be the most logical way to abstract away all the platform-specific dll loading?
(OPTIONAL) Are there some unforeseen problems that I might encounter?
1) generally, yes. If the API gets complex and multi-object, I'd use COM or a similar mechanism. But if you have to manage only a little state, or can go completely state-free, a pure DLL interface is fine.
2) Use a suitable calling convention (stdcall) and data types. I would not even asusme that the implementation has to be in C++. so that means char/wchar_t, explicit-sized ints, e.g. int32 , float and double, and C-style arrays of them.
3) can't say
4)
No cross-boundary memory allocations: free what you allocate, and let the plugin free what it allocated.
Your API design has a big influence on achievable performance and implementation effort. DOn't make the functions to small, give the implementation some freedom how it handles certain things, define error protocol, threading requirements etc.
[edit]
Also, if you declare structures, look into alignment and compiler options to control this (usually #pragma pack). This is required so clients see the same layout.
The compiler usually "mangles" the names for the exported symbols (e.g. add an udnerscore for STDCALL convention). Typically, this is controlled through a .def file that is passed to the linker.
Yes, it is. But there are many issues.
May or may not. Firstly, you should be aware of calling conventions. Secondly, since there is no standardized ABI for C++, you should stick to plain C at interface level (Btw, COM technology was all about this -- making a standardized ABI). Thirdly, each plugin may have its own CRT and so problems may appear, there is a good article about this on MSDN.
Yes, this will help with loading dynamic libraries, but not with problems in (2). Althought, these problems mostly windows specific.
In my experience, QLibrary is the best answer to your questions.
It provides a simple interface and takes care of all the platform-specific details.
Indeed, that means that the plugins must be also written using QT.

Splitting up a utility DLL into smaller components in C++

We have a core library in the form of a DLL that is used by more than one client application. It has gotten somewhat bloated and some applications need only a tiny fraction of the functionality that this DLL provides. So now we're looking at dividing this behemoth into smaller components.
My question is this: Can anyone recommend a path to take to divide this bloated DLL into a set of modules that have some interdepencies but do not necessarily require all other modules?
Here are the options as I see them but I'm hoping someone can offer other possibilities:
Create a "core" dll and several "satellite" dlls which use the core and possibly other satellite DLLs.
Subdivide the contents of the bloated DLL into static libraries that the main DLL uses (to maintain the same functionality) but apps that don't want to use the bloated version can assemble the static libraries they need into their own dll or into the app itself.
I was hesitant to mention this but I think it may be important to note that the app uses MFC.
Thanks for your thoughts.
Somewhat related to your question is this question, about splitting up a very large C module into smaller ones.
How do you introduce unit testing into a large, legacy (C/C++) codebase?
It seems your question has to do with the larger question of breaking some large blob of code into a more modular system. The link above is definitely recommended reading.
Without having all the details it is a little hard to help but here is what I would do in your situation
provide both static and dll versions of whate3ver you release - for MT and single threaded.
try to glean from the disparate clients which items should be grouped together to provide reasonable segmentation - without having layers of dependencies.
having a "core" module sounds like a good idea - and make sure you don't have too many levels of dependencies - you might want to keep it simple.
You may find after the exercise that one big dll is actually reasonable.
Another consideration is that maintaining multiple DLLs and both static libs and DLLs will hugely increase the complexity of maintenance.
Are you going to be releasing them all at once every time, or are they going to be mix and match? Be careful here - and know that you could create testing issues
If no one is complaining about the size of the DLL then you might want to consider leaving it as is.