Combining C++/CLR and C++ - c++

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.

Related

How to reuse C++ classes from one project to another without copying

I am facing the following problem:
I have a project which contains math classes (.h and .cpp files).
I want to use these classes in a different project (not int he same solution) but I can't.
In the new project I add a path to the include files of my math project. When I try to #include them it works and I can see my classes but upon trying to use them I get "Unresolved external". I haven't created a .dll or a .lib so I really don't know what's causing this.
If you have any suggestions, I`ll appreciate it.
Thank you very much in advance.
When I try to #include them it works and I can see my classes but
upon trying to use them I get "Unresolved external". I haven't created
a .dll or a .lib so I really don't know what's causing this.
That you have not created a library is precisely the reason why you get the error. The compilation units in your new project ("the *.cpp files") include the headers for your classes and make use of the class definitions, but the definitions of the members are missing.
For example, let's say you have a file called "c.h" in your old project:
#ifndef C_H
#define C_H
class C
{
public:
C();
void f();
};
#endif
Some *.cpp file in your new project includes the header and uses the class:
#include "somepath/oldproject/c.h"
void someFunction()
{
C c;
c.f();
}
This compiles fine, but it will cause linker errors, because the definitions of C::C and C::f will be missing.
Now, the clean solution to this is certainly not adding somepath/oldproject/c.cpp from your old project to your new project, although that would fix the linker error, but to employ a library-based approach. Turn your math classes into a library project, let's call it "Math Utils", which produces a *.lib file (as you seem to be on Windows), for example math-utils.lib. Add the library's include and release path to your global include and library paths. Then add the math-utils.lib file to the new project's linker dependencies.
And change the code in your new project to:
#include <math-utils/c.h>
void someFunction()
{
C c;
c.f();
}
Do the same thing in the old project! You will end up with three different projects. Two application projects and one library project, the former two depending on the latter.
Creating your own libraries for the first time can be a bit intimidating, but the benefits are worth the trouble.
See also The Linker Is not a Magical Program.

How to force include static objects from a static library in C++ (MSVC 11)

I am trying to initialize a static object in a C++ file which is trying to auto register a class to a factory in its constructor (like any standard auto-registration problem). The problem is, this is compiled to a static library, and while linking to an executable, that is optimized away. There should have been a very simple solution to that, but surprisingly, looks like it's not that simple.
Here's my class:
In Factory.h (part of static lib project)
class DummyClass : public BaseFactoryClass
{
int mDummyInt;
public:
DummyClass()
{
std::cout << "Pretending to register myself to the factory here\n";
}
};
In some cpp, let's say Circle.cpp (still part of the static lib project)
static DummyClass dum;
main.cpp (part of the executable)
//some code accessing the BaseFactoryClass of the Registered derived classes.
Now, since the static object is not 'directly' used in the executable project, it's skipped from the linked library.
I want to make it work in MS VC11 (Visual Studio 2012) (and GCC 4.8.*, but that's for later). Looking at other questions, I tried various things so far, which don't seem to work:
Looks like /WHOLEARCHIVE linker option is only supported from Visual
Studio 2015 (We're using VS 2012)
Specifying /OPT:NOREF should have worked (I tried several combination of this with other flags like /OPT:NOICF), but it doesn't work for anyone.
I tried #pragma comment (linker, "/include:symbolName") in the header file, but that gives a linker error about symbol being unrecognized. (And also that wouldn't work in GCC, but probably --whole-archive works there).
There is a flag in Visual Studio Linker Settings that allows linking all object files individually rather than the static lib, but I don't want to go that route. Also, preferably I'd just want to write something in the source (.cpp) of each individual class I want to automatically register, with all the boiler plate code and macros being in a central header like BaseFactory.h etc. Is there any way to do it (even in C++ 11 where there's a guarantee that a symbol will be initialized)? Want to make the registration of a new class as easy as possible for any new developer.
In MSVC you have a linker pragma you can use for that purpose:
#pragma comment (linker, "/export:_dum")
This way whenever the linker is run, it will force link _dum in your executable or DLL.
A better way, though, would be to consider using a DLL instead of a static library. Then you avoid this problem altogether since on each load of the DLL that static variable will be initialized.

Best practice when producing a C++ static or dynamic library for others?

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.

#pragma comment(lib) v #import?

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.

C++ Avoiding library linking

I currently have a c++ setup like the following
class FlowController
{
public:
//...
private:
cntrl::OneWayValve _intake;
}
As you can see i'm using a cntrl::OneWayValve instance within my class. The Valve class resides in another library which i link with at compile time. The cntrl::OneWayValve has a cntrl::Value within its implementation like so.
class OneWayValve
{
public:
//...
private:
cntrl::Valve _valve;
}
And as before the cntrl::Valve resides in a different library for reasons you'll have to ask the previous developer about.
Now when i compile my FlowController class i'm required to link with the OneWayValve library and the cntrl::Valve library as well.
My question:
Is it possible to only link with the cntrl::OneWayValve library at compile time?
Forward declaration?
Static libraries (really don't want to do this tho)?
Another alternative?
Basically i don't want to know that its using a cntrl::Valve internally, its none of my business.
Note: apologies the OS is Unix.
Cheers,
Ben
What you could do is make your Valve library part of your OneWayValve library using a tool called a librarian. I don't know what OS/compiler you are using so I'm going to describe how do it using Visual Studio since that's the only system I've actually done this with (unless you want to count CP/M + LIB-80 :-)
If you bring up the Tools|Options dialog for you OneWayValve project and select Configuration Properties|Librarian|Additional Dependencies, you can put a reference to your Valve library in the Additional Dependencies setting. This will cause OneWayValve.lib to contain any objects that it references from Valve.lib.
Unfortunately for you, the OneWayValve isn't very well designed. Not only you need to link to both libraries, but you will also have to recompile both the OneWayValve library and your code if the Valve class changes.
You can do it by defining all methods of OneWayValve and Valve in their headers as inline. Then you don't need to link to the library.
But if it was designed that way, then what problems are linking to this library causing? Nothing wrong with dynamically linking a library.