I am still reasonably new to C++ and am trying to get my head around static libraries and DLLs. I have just inherited some code and wondered if someone could give me a clarification.
The inherited code contains two library projects, call them a and b. There is also the main project, which uses classes from both the libraries.
The bit I am confused about is this: both project a and project b, when built, output both a .dll to "..\.\Executables" and a .lib to "..\Shared\Lib". The stdafx.h of the main project includes library a with the following code:
#include ..\projectA\a_class.h
#pragma comment( lib, "..\\Shared\\Lib\\projectA.lib" )
... and it includes library b using the following code:
#import "..\..\Executables\projectB.dll"
It then utilises classes from both libraries. What is the difference between the two? Why is it that when I try and include library A using method B, it does not work (the classes are not accessible)?
Thanks in advance!
They do different things. You use #import to import a type library and to generate wrapper classes for COM objects. The fact that a type library can be a tlb or can be encapsulated in a dll (or as an ocx which is the same thing with a different name) is confusing. The only thing you missed is that #import is only ever to do with COM.
The "normal" #pragma comment(lib, "blah.lib") - which is an alternative to defining additional libs in Project Properties - is for linking to a static or dynamic library and is just used to import the functions and symbols exported by the lib itself. No wrapper classes are generated and it has nothing to do with COM.
You can read more about #import at MSDN here and more about the #pragma option at MSDN here.
Related
I'm providing a Microsoft C++ library (static and dynamic) for other clients in my company. My library has a few classes that depend upon functions located in common Windows DLLs whose import libraries aren't included in the project link settings by default.
Rather than add a new import library name to the linker section of every build configuration of my library each time a new dependency like this came up, I thought it would be better in terms of encapsulation of dependencies (and a bit more self-documenting) if I used #pragma comment(lib, ...) in the .cpp file of the class that depended upon a function from such a DLL, e.g.:
Foo.cpp:
#include <SomeWinLib.h>
#pragma comment(lib, "somewinlib.lib")
... implementation of Foo class ...
...but I found that this was causing link warnings/errors for clients of my library if they were also using SomeWinLib. After doing some reading on the subject, it seems that the recommended/best practice is to let the client who is linking in my library also link in the libraries it depends upon.
I still wanted this to be as automatic/painless as possible for the clients, so rather than just put a list of required import libraries in a readme.txt file (and then sit back and wait for the inevitable phone calls from frustrated developers), I'd just place the #pragma comment in the Foo.h header file. That way, clients would automatically link in the required library if they included the header file of a class that required it.
Foo.h:
#pragma comment(lib, "somewinlib.lib")
public class Foo
{
However, when I build my library, Foo.cpp includes Foo.h obviously, so it would seem that I need some kind of preprocessor "guard" around the #pragma comment line in the header file so that it's only seen by the preprocessor when clients include my header file.
Foo.h:
#if !defined(building_my_library)
#pragma comment(lib, "somewinlib.lib")
#endif
public class Foo
{
All of this seems like something that pretty much EVERY library must be doing, yet I don't see examples of this when I Google other open source Windows libraries. That makes me suspect I've missed something somewhere.
Does anyone know if I'm understanding the issues correctly, and if so, whether I'm over-complicating the solution?
Thanks!
Your last option is more or less what the boost headers do, except they also provide a preprocessor directive to explicitly turn off the auto-linking in case you want to control things yourself:
#if !defined(building_my_library) && !defined(no_auto_link_stuff)
#pragma comment(lib, "somelib.lib")
#endif
A solution that you might not have considered is to use runtime linkage to the DLL via LoadLibrary and GetProcAddress, removing the dependence on somewinlib.lib.
I'm in DLL hell. I have 2 DLLs let's say A.dll and B.dll which have a name collision - the same C++ class name is used in each, etc. Both DLLs are available as static libs.
Can I create a 'wrappe' DLL, say Aprime.dll which exports a similar class, methods, etc. as in A.dll, and delegates the functionality to the class in A.lib, but statically linked into the Aprime.dll? Wouldn't that avoid the name collision?
I've been trying this, but not sure I have the MSVS project set up correctly. Aprime.dll is being produced, but according to Dependency Walker Aprime.dll is still loading A.dll.
I've been searching, but most stuff I find applies only to statically linking in the CRT or MFC, which have their own switches.
I added A.lib under Linker -> Input -> Additional Dependencies.
Am I missing some magic linker command line switch or something?
Yes that method should work. The key though is to ensure that you do not include any of the original A.dll header files in the Aprime.dll header file. Otherwise if someone includes Aprime.h/pp then it will include A.h/pp and you will then have a clash again.
So you want something like:
A.h
// Library A includes
class test
{
};
B.h
// Library B includes
class test
{
}
Aprime.h
// Proxy class
class myTest
{
}
Aprime.cpp
#include "A.h"
#include "Aprime.h"
...
main.cpp
#include "Aprime.h"
#include "B.h"
...
Note that main never includes both A and B. In only includes Aprime and B. B is still static lib and Aprime is a DLL.
Yes, you can, and it's supported at a very low level by Windows. Aprime.DLL is effectively empty except for a bunch of references to A.DLL.
I want to include third-party C++ libraries in my C++/CLI application.
What is/are the standard method(s) for doing this?
Thanks in advance.
I don't know if such standard exists, you can use C++ libraries from within C++/CLI application like you do with C++ apps.
The only thing I always try to do is to wrap 3rd library behind Proxy or Facade design pattern, so that the client would always work with managed classes.
This is especially important if your C++/CLI app is a library used by other .NET apps.
Example:
// 3rd party header
class Value{};
// your C++/CLI app
#include <3rdpaty/Value.h>
public ref class ValueWrapper
{
public:
// wrapper interface here
private:
std::scoped_ptr<Value> value_;
};
There's very little to it, C++/CLI was explicitly created to support this scenario. Just pick a project template from the CLR node to get started. You'll have to tell the linker to link the .lib files and #include the headers in your C++/CLI source code.
The only wrinkle you can run into is that the #include headers might contain declarations that can be misinterpreted by the C++/CLI compilers. C function declarations for example. Best thing to do is to the tell the compiler explicitly about it. Like this:
#include "stdafx.h"
#pragma managed(push, off)
#include "3rdparty.h"
#pragma managed(pop)
#pragma comment(lib, "3rdparty.lib")
// Rest of your code
The #pragma comment in that snippet tells the linker to also link the .lib file of the 3rd party library. Saves you from having to do it explicitly in the linker's Additional Dependencies setting.
That's all.
I'm having trouble wrapping my head around how to interface with C/C++ libraries, both static (.lib/.a) and dynamic (.dll/.so), in D. From what I understand, it's possible to tell the DMD compiler to link with .lib files, and that you can convert .dll files to .lib with the implib tool that Digital Mars provides. In addition, I've come across this page, which implies being able to call functions in .dlls by converting C header files to D interface files. Are both of these methods equivalent? Would these same methods work for Unix library files? Also, how would one reference functions, enums, etc from these libraries, and how would one tell their D compiler to link with these libs (I'm using VisualD, specifically)? If anyone could provide some examples of referencing .lib, .dll, .a, and .so files from D code, I'd be most grateful.
Note you are dealing with three phases for generating an executable. During compilation you are creating object files (.lib/.a are just archives of object files). Once these files are created you use a Linker to put all the pieces together. When dealing with dynamic libraries (.dll, .so) there is the extra step of loading the library when the program starts/during run-time.
During compilation the compiler only needs to be aware of what you are using, it doesn't care if it is implemented. This is where the D interface files come in and are kind of equivalent to Header Files in this respect. Enumerations are declared in the D interface file and must also be defined because they only exist at compile time. Functions and variables can just be declared with no body.
int myFunction(char* str);
The guide for converting a header file to D is in the page you referenced. These files can then be passed to the compiler or exist in the Include Path.
When the linker runs is when you'll need the .lib/.a file. These files can be passed to the compiler which will forward them to the Linker or you can use pragma(lib, "my.lib"); in your program. In both cases the linker must be able to finding at link time (compilation).
In Linux I don't believe there is a difference for linking dynamic and static. In Windows you don't even need the D interface file. Instead you must obtain the function through system calls. I'm really not that familiar with this area, but I suggest Loading Plugins (DLLs) on-the-fly
Update: I can't help much with VisualD, but there is D for .NET Programmers.
There samples in D distribution of how to do this.
You need to define thunk module like this:
module harmonia.native.win32;
version(build) { pragma(nolink); }
export int DialogBoxParamA(HINSTANCE hInstance, LPCSTR lpTemplateName,
HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam);
and include import libs of DLLs where functions like DialogBoxParamA are defined.
Been a while since I have programmed in C++, so the whole export/import idea slipped off my mind.
Can you explain me why to use __declspec(dllexport) & import thingy if it looks like I can use classes from other libraries without those.
I have created a solution in VC++ 2005, added the console applicaiton project and two dll libraries projects. Then create ClassA in a LibA, ClassB in LibB project.
Once I have included ClassA.h & ClassB.h into my console app source code, and has linked it with a LibA.lib and LibB.lib I was able to create and use instances of ClassA and ClassB in a console applicaiton. So basically I was able to use classes without exporting/importing them using __declspec.
Can you explain me - what I am missing here.
Once I have included ClassA.h & ClassB.h into my console app source code, and has linked it with a LibA.lib and LibB.lib I was able to create and use instances of ClassA and ClassB in a console applicaiton.
This sounds like you have used static linking. This works without the __declspec(dllexport) in the same way as linking with the object files of your classes directly.
If you want to use dynamic (run-time) linking with a DLL, you have to use either the mentioned declaration or a DEF-file specifying the exported functions. DLLs contain an exports table listing the functions exposed to other executables. All other functions remain internal to your DLL.
Perhaps you are confused coming from the Linux world, where the situation is the other way round: All symbols are visible externally by default.
You would use __declspec(dllexport) if you wanted to provide symbols in your dll for other dlls/exes to access.
You would use __declspec(dllimport) if you wanted to access symbols in your dll/exe provided by another dll.
Not necessary if you are linking against a static .lib.
If you are including .h files and linking to .lib files then you can drop the DLL declarations. Why do you need a dynamic link library if you only need static linking?
The export declaration marks the function as available for exporting. The declaration you are using may be a macro for "extern" and "pascal" It's been years since I've done this but I think DLLs function calls have a different ordering of pushing params on the stack and the allocation of the return result is done differently (the pascal flag). The extern declaration helps the linker make the function available when you link the library.
You may have missed the step of linking the DLL - the linker will take classA.lib and turn it into classA.dll ( you may need to setup a setupA.def file to define the DLL library). Same applies to ClassB