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.
Related
I have a library I'm building which is targeted to be a DLL that is linked into the main solution.
This new DLL is quite complex and I'd like to make use of C++11 features, while the program that will link it most certainly does not. In fact, the main program is currently "cleanly" built using VS2008 and VS2010 (and i think GCC 4.3 for linux?).
What I propose:
Using VS2012 as the IDE and Intel C++ Compiler 2013 for compilation to .dll/.so - for linux - which, as I understand, is basically down to machine form (like an .exe).
While I'm familiar with using C++ to solve problems, I am not fluent in the fundamentals of compilation/linking, etc. Therefore, I'd like to ask the community if
This is possible
If it is possible, how easy is it (as simple as I described?) / what pitfalls or issues can I expect along the way (is it worth it)?
Areas of concern I anticipate:
runtime libraries - I expect this to be the factor that derails this effort. I know nothing about them/how they work except that they might be a problem.
Standard Library implementation differences - should it matter if it's down to DLL form?
threading conflicts - the dll threads and the main programs threads never modify the same data, and actually one of the main program's threads will call the DLL functions.
Bonus: While the above is the route I expect to take, I'd ideally like to have this code open for intellisense, general viewing, etc (essentially for it to become a project in the main solution). Is there a way to specify different runtime libraries/compiler? Can this be done?
EDIT: The main reason for this bonus part is to eliminate the necessary "versioning" conflicts that will arise if the main program and this library are built separately.
NOTE: I'm not using C++11 just for the sake of being newer - strongly typed enums and cross-platform threading code will be huge bonuses for the library.
The question isn't so much "Can an application use a library built with a different compiler ?" (The answer is yes.) but "What C++ features can be used in the public interface of a library built with another compiler and C++ standard library?"
On Windows, the answer is "almost none". Interfaces (classes containing only virtual functions) are about it. No classes with data members. No exceptions. No runtime objects (like iostream instances or strings). No templates.
On Linux, the answer is "lots more but still not many". Classes are ok, as long as the ODR is satisfied. Exceptions will work. Templates too, as long as the definition is exactly the same on both sides. But definitions of standard library types did change between C++03 and C++11, so you won't for example be able to pass std::string or std::vector<int> objects between the application and library (both sides can use these features, but the same object can't cross over).
I'm afraid this is not possible with C++. Especially name mangling can be different. All C++ files linked together need to be compiled with same compiler.
In C++, extern "C" stuff is standard (naming, calling convention), so C libraries can be called from C++, as well as C++ functions declared withing extern "C" block. This exludes classes, templates, overloads, mixing them compiled by different compilers is not workable.
Which is a pity.
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.
In writing Win32 C/C++ code, is there any advantage (e.g. performance?) in using Windows-specific functions like lstrcpyn or CopyMemory instead of the corresponding CRT functions (aside from portability of CRT functions)?
At least some CRT functions use the Win32 functions internally. Also the CRT requires additional initialization (e.g. thread specific data for functions like strtok) and cleanup, that you might not want to have to happen.
You could create a plain Win32 application, without any dependency on anything else including the CRT (much like you could create a plain NT application using NTDLL.DLL - I think smss.exe of Windows is such a process BTW).
Having that said, I think that for most applications that doesn't matter.
UPDATE Since people seem to get so hooked up on the difference of individual functions, in particular memcpy vs. CopyMemory, I would like to add that not all functions in CRT are wrappers around those in Win32. Naturally, some can be implemented without any help from Win32 (actually memcpy is a good example for that), while others (sensibly) can't. Something that, I believe, #Merdad hinted in his answer to.
So, portability aside, I don't think performance is the next best argument for or against using the CRT.
You should choose what fits best and that typically will be the CRT. And there is nothing speaking against using individual Win32 functions (with CRT equivalents), where you seem fit.
It depends on the function and your requirements.
For things like memcpy, there isn't any point whatsoever to choosing the Windows-specific versions. Stick with standard C to keep it simple and portable.
For other things like mbstowcs, you might need to use things like MultiByteToWideChar instead -- depending on what functionality you need.
Personally I go for the C versions if possible, and only go for Win32 versions afterwards -- because there's really no reason to write Windows-specific code when it could be written portably.
Many of the standard c library (fwrite, memset, malloc) functions have direct equivalents in the Windows Api (WriteFile, FillMemory/ ZeroMemory, GlobalAlloc).
Apart from portability issues, what should be used, the CLIB or Windows API functions?
Will the C functions call the Windows Api functions or is it the other way around?
There's nothing magical about the C library. It's just a standardized API for accessing common services from the OS. That means it's implemented on top of the OS, using the API's provided by the OS.
Use whichever makes sense in your situation. The C library is portable, Win32 isn't. On the other hand, Win32 is often more flexible, and exposes more functionality.
The functions aren't really equivalent with the exception of some simple things like ZeroMemory.
GlobalAlloc for example gives you memory, but it was used for shared memory transfer under win16 as well. Parts of this functionality still exist.
WriteFile will not only write to files but to (among others) named pipes as well. Something fwrite or write can't directly do.
I'd say use c library functions if possible and use the windows functions only if you need the extra functionality or if you get a performance improvement.
This will make porting to other platforms easier later on.
It's probably more information than you're looking for (and maybe not exactly what you asked) but Catch22.net has an article entitled "Techniques for reducing Executable size" that may help point out the differences in Win32 api calls and c runtime calls.
Will the C functions call the winapi functions or is it the other way around?
The C functions (which are implemented in a user-mode library) call the WINAPI functions (which are implemented in the O/S kernel).
If you're going to port your application across multiple platforms I would say that you should create your own set of wrappers, even if you use the standard C functions. That will give you the best flexibility when switching platforms as your code will be insulated from the underlying system in a nicer way.
Of course that means if you're only going to program for Windows platforms then just use the Windows functions, and don't use the standard C library functions of the same type.
In the end you just need to stay consistent with your choice and you'll be fine.
C functions will call the system API, the Standard Runtime C Library (or CRT) is an API used to standardize among systems.
Internally, each system designs its own API directly using system calls or drivers. If you have a commercial version of Visual C++, it used to provide the CRT source code, this is interesting reading.
A few additional points on some examples:
FillMemory, ZeroMemory
Neither these nor the C functions are system calls, so either one might be implemented on top of the other, or they could even have different implementations, coming from a common source or not.
GlobalAlloc
Since malloc() is built on top of operating system primitives exposed by its API, it would be interesting to know if malloc() and direct usage of such allocators coexist happily without problems. I might imagine of some reasons why malloc might silently assume that the heap it accesses is contiguous, even if I would call that a design bug, even if it were documented, unless the additional cost for the safety were non insignificant.
Well, I'm currently trying to avoid including fstream, sstream, iostream and many C standard library files and using winAPIs instead because including any of these libraries increases the size of the output executable from about 10 KB to about 500 KB.
But sometimes it's better to use the C standard library to make your code cross-platform.
So I think it depends on your goal.
I need to build a C++ library to distribute among our customers. The library must be able to be accessed from a wide range of languages including VB6, C++, VB.net and C#.
I've being using ActiveX controls (ocx files) until now. But I wonder if there is a better kind of library (dll, etc.) that I can build. What do you recommend?
I'm limited to C++ as the library language, but you can mention other languages for reference to other developers.
P.S. Sorry if the question was already asked. I had some trouble finding a suitable title. Feel free to correct my English.
Edit: Seems like the best choice is either DLLs or OCX (i.e., COM), but I'm still having some doubts on which one will I choose. Which one is more suitable to modern languages (.NET for instance)? Which one would be easier to use from an end developer perspective?
Almost every language has a way of loading dynamic libraries and accessing exported C functions from them.
There is nothing preventing you from using C++ inside the dll but for maximum portability, export only C functions.
I have some more about this in this post.
If you're looking at supporting both VB6 and .NET, you're pretty much stuck with exposing interfaces via COM, but at least that'll get you out of having to create more than one wrapper based on the language/runtime system you're trying to interact with.
If there is any chance this will need to be ported to non windows platforms then a DLL / Shared library is your best choice as a COM object really isn't at all portable.
In addition you can call a DLL from almost any platform even if it requires you to write a wrapper of some kind. It's pretty easy to wrap a dll in a com object but if you make a native com object it's a lot harder to add a C style DLL API. Plus you might want to call it from java for example and it's much easier to write a JNI wrapper to call your DLL than get it working with COM in any kind of cross platform way.
Really it depends on what platforms you really need to call it from and how certain you can be that you won't get something out of the ordinary in future.
To be callable from all those languages your only real option is going to be COM, without having to write wrappers where required (which would defeat the point)