MSVC - boost::python static linking to .dll (.pyd) - c++

I got a VS10 project. I want to build some C++ code so I can use it in python. I followed the boost tutorial and got it working. However VS keeps to link boost-python-vc100-mt-gd-1_44.lib but it's just a wrapper which calls boost-python-vc100-mt-gd-1_44.dll. That's why I need to copy the .dll with my .dll(.pyd) file. So I want to link boost:python statically to that .dll(.pyd) file. But I just can't find any configuration option in VS or in the compiler and linker manual. The weirdest thing is I've got one older project using boost::filesystem with the very same config but that project links against libboost-filesystem-*.lib which is static lib so it's ok. I've been googling for couple of hours without any success and it drivers me crazy.
Thanks for any help or suggestion.

You probably don't want to do that. Statically linked Boost python has a number of problems and quirks when there are more then one boost python based library imported. "But I only have one" you say. Can you guarantee that your users won't have another? That you might want to use another in the future? Stick with the DLL. Distributing another DLL is really not that big a deal. Just put it side-by-side in the same directory.

What libraries are linked depends on the settings of your project. There are two possibilities: You can build against
statically
dynamically
linked versions of the c-runtime libs. Depending on which option is selected, the boost sends a proper #pragma to the linker. These options need to be set consistently in all projects which constitute your program. So go to "properties -> c++ -> code generation" (or similar, I am just guessing, don't have VS up and running right now) and be sure that the right option is set (consistently). Of course, you must have compiled boost libraries in required format before...

Related

What is the proper way to include a source library in a Visual Studio C++ project?

Right now I'm trying to create my first "real" project in C++ using Visual Studio 2019. I need to include a third-party library as a dependency. The instructions on the project homepage simply recommend to include all source/header files directly into the project. My understanding is that it's a bad practice, since the end result would look quite ugly in any VCS.
Thankfully, the library author also provided build scripts that call cl, lib and link with appropriate arguments and produce the coveted foo.lib. I added that file to dependencies in linker options and after some haranguing with compiler/linker options finally got it running.
To my distress, I realised that I've done all those manipulations in Release configuration, which prevented me from using the debugger. I then built the library with /MDd, fixed some compiler options... and got a bizarre compile-time error in vcruntime.h ( fatal error C1189: #error: _HAS_CXX17 and _HAS_CXX20 must both be defined, and _HAS_CXX20 must imply _HAS_CXX17).
At this point, I knew I was doing something terribly wrong, since including a simple library should't require so much manual knob-tweaking. What is the right, canonical way of including third-party dependencies in Visual Studio (and C++ in general)? Assuming the dependency isn't available on Nuget, vcpkg or somesuch.
As I understand from the stuff you did was on Windows. First of all I would recommend you try a linux distro. In windows it is possible to get lib files running, but not easy. It would help if you could send me a link to the library you are using.
The usual approach is to just stick those sources in their own directory and their own Visual Studio project (not solution). This can still build a foo.lib. You won't need many options for this.
Next, you just tell Visual Studio that your own project depends on that other project, and it will then link foo.LIB for you.
Having said that, it sounds like you try to build your two projects with different settings for the C++ version. VS2019 has good support for C++17 and experimental support for C++20, so you can choose. But you need to choose consistently for all your projects.
In larger solutions you can us a .vsprops file for that, which is like an #include for project files. A bit overkill when you have two projects, a lifesaver when you have 150.
It varies a bit how you include 3rd party libraries, sometimes 3rd party libraries have an installation and install themselves like under Common Components sometimes you have to do it manually.
E.g. YourSolution/3rdParty/foo/include
YourSolution/3rdParty/foo/lib
YourSolution/3rdParty/foo/lib/release
YourSolution/3rdParty/foo/lib/debug
Sometimes the libraries have different names then they may be in the same folder.
Once you have that structure go to your project's properties C/C++ and add the include under Additional Include Directories make sure you have configuration "All Configurations" here. Then go to Project properties/Linker/Input and the dependency for Debug Configuration and for the Release Configuration - since usually they are different libraries per configuration. e.g. release/foo.lib and debug/foo.lib (foo.lib foo-d.lib or whatever they are called).
Use the macros to make sure you get the right locations so that they are relative to your solution and project. It is not good having absolute paths. E.g. $(SolutionDir)3rdparty\foo\include
Disclaimer : I am not sure this is the "optimal" way to do it but that is the way I do it.

C++ Linking static librarys to a dynamic library

It's a bit annoying.
I have a project that is entirely dynamically linked, but I want to use a library that seems to be only designed to be statically linked, using the /MT flags, Is it possible to build a separate dll to link to the static libs and then link to that In my project?
I apologise for the rushed explanation, I'm quite tired.
The library in question is the bullet physics library.
Edit:
Well, with more googling, it appears that there can be a /MD/MDd compiled version, though I'm not sure where It's located.
Edit(for anyone interested):
According to this page: http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=3846
"If your entire engine is compiled with the /MD flag then you would use the 'release DLL' version of bullet. You should not mix libraries compiled with /MD with ones compiled with /MT. That's the main difference. There is no "separate DLL (.dll)" files for bullet."
Edit: And If I build it using the MSVC Runtime library, then it fails.
In short, I have no idea what to do.
He's what I'm doing:
Building the whole library in cmake, using the Visual studio 12, 2013 compiler.
Then building the project built by cmake, to build all the required projects.
This is the supplied instructions. Here
Last Edit:Thank you all so much for you help! I managed to build it in the end
Sorry for any spelling mistakes, I was quite tired at the time :3
Short answer, yes.
Although you could just have the dynamic libraries link to it, there are scenarios where this may cause serious problems, depending on how the library was written (state information, etc.).
Although it's more work, a wrapper DLL is probably the safest course of action. However, this is offset by the fact that you only need to wrap the functions actually called from the various components of your application, not the entire API provided by the library. Also, you'll need to have some kind of slight rename to the functions you actually wrap, to prevent ambiguity.
On edit:
Just took a look at the bullet physics library, as I was not personally familiar with it and was curious about your options after I initially answered. If they're that explicit about not supporting dynamic builds for the library, I think wrapping whatever functions you actually use would definitely be safest. That sucks. I hope it's not too large of a cross-section.

Linking to Boost Regex library in VS2012

I'm trying to build my VS2012 C++ project using Boost Regex library. It seems that the linker does not find the library and gives the error:
error LNK1104: cannot open file 'libboost_regex-vc110-mt-gd-1_50.lib'
In "Project Properties:Linker:General:Additional Library Directories", I included a path which (within a subdirectory) contains a library named boost_regex.lib.
This was built by a 3rd party framework (FireBreath), and I shouldn't change it. How do I get VS2012 to use this library instead of looking for one under the name referenced in the error?
Firstly, what makes you so sure that the boost_regex.lib is the right one? Is it even for your compiler and version? I also doubt that it is for the debug variant of the runtime library. My guess is that you will have to build this for the compiler that you're using and properly install it, for which there are instructions at the Boost website. This might also imply rebuilding FireBreath for your compiler, assuming that's a C++ library, too.
Then, the code in Boost that detects compiler settings and then selects a library to link against is correct for normal setups. This code uses "#pragma comment(lib, ...)" to specify the lib to link with, so you should be able to find the code. There, you should also be able to detect the macros that turn this feature off. However, you are probably not fixing anything with that but rather you are creating more problems.
Substituting the library is not something you want to do. Instead:
Download Boost into, say, c:\boost
Open a VS command prompt, go into c:\boost and run bjam. When this is done, run b2. Wait.
Now go into your project and add c:\boost\stage\lib to the Additional Library Directories setting.
This will allow you to build the project.

Using 3rd Party Libraries in C++

I'm totally spinning my wheels with getting a couple of 3rd party libraries to work with my c++ programs. I'm looking for some general advice (40,000 foot level) about the general steps that one needs to take when implementing libraries.
First, some specifics: I am using code::blocks in Windows as my IDE. I like this IDE and really don't want to switch to anything else if I don't have to (I've tried visual c++ and also some things in linux). The libraries that I am trying to use are GMP and crypto++.
OK. What I think I know is this: After downloading the library, I unzip the file to a folder. I've been unzipping directly to C:\ with each zip file extracted to its own folder (e.g. c:\cryptopp and c:\gmp). I think that the next step is to build the library, but this is where I get totally stuck. How is this done? There are no executable files among those extracted. From what I can tell, I believe that I do this in code::blocks, but I have no idea how?
Finally, assuming that I can get this done, which I believe creates the .lib files, the last step before actually using the library in my code, is to link into the library. This part, I believe that I understand.
So, my question is broad: do I understand this process overall? And if so, how do I go about building these libraries, if in fact that it the thing that I am missing.
Thanks very much for indulging my ignorance. I'm totally rudderless right now and despite hours and hours on google, I'm making no progress. Also, feel free to correct anything that I have stated as fact that is not correct. Thanks a lot!
Usually libraries have a special file called makefile in them, and are built with a utility called Make (or one of it's variations, whatever works uder windows).
Usually all you have to do is to run Make in the directory where you have unpacked the source files, and it will do the rest itself.
If those libraries you mention (GMP and crypto++; disclaimer: I'm not familiar with either of them) don't have project files for code::blocks then you may still be able to compile them under Windows with MinGW.
If you have installed MinGW you use the MinGW shell to navigate to the appropriate directories which would be /c/cryptopp/ and /c/gmp in your examples - The MinGW shell works like a Unix shell, and has different naming conventions.
Then you need to compile the libraries. Check whether there's a Makefile in those directories, if there isn't you can check whether there's a configure script, which will generate the Makefile. If you have the Makefile you can type make which will compile the libraries with MinGW's port of the GCC compiler.
When the compilation is complete you should have a library in the form of a .a file (say libcryptopp.a) that you can link to your project. In code::blocks you would set the linker path (the -L command line option in GCC) to C:\cryptopp\bin or wherever the library has been compiled, and then add libcryptopp.a to the list of libraries you want to link (this is associated with the -l option in GCC). The convention is to leave out the lib prefix and the .a extension, so you would just add cryptopp to your library list. In the end your linker options should look like -LC:\cryptopp\bin -lcryptopp along with the
Also, to be able to use the libraries you need to add the path to the headers directory to the include path of your project. This is associated to the -I command line option in GCC, so your compiler's command line options would have something like -IC:\cryptopp\include somewhere.
Of course, all of the above assumes that you use code::blocks with GCC. If you're using it with VisualC++ then the principles are the same, but the specific steps differ.

How do I use some specific dll in c/c++?

Like the msvcr70/msvcr80/msvcr90.dll, what's the code like to instruct the linker to link to one of them dynamically?
Or has that anything to do with c/c++,but cmake?
The specific examples you give happen to be DLLs that are usually linked through manifests and the side-by-side, at least when building applications (with the correct project settings) from Visual Studio. Why are you trying to instruct the compiler to link them by code?
The most often-used way to link to a particular DLL is when you have the lib for the DLL available, and then to use the pragma
#pragma comment(lib, "<library name>")
You specify a .lib file when you link, and the matching .dll will be used at run time, so (for example) if you want to use msvcr70.dll, you'll want to link with msvcr70.lib.
In general, the C/C++ runtime you link against is dependent to the version of VisualStudio you are using. (msvcr80.dll -> VS2005, msvcr90.dll -> VS2008 etc.)
Some deeper insight on how this works and some tricks to work araoud this you can read up in this blog post.
eh, surely you want to first understand DLLs/linking... http://www.infernodevelopment.com/how-create-dll-c-using-run-time-dynamic-linking
the question as written is not answerable
Note: not sure what you mean with Cmake, but you can easily specify link libraries in your CMakeLists.txt file... the exception being the DLLs you note, because they are platform-dependent. You'd need something in the CMake script to check versions of MSVC.
Why would you want to link to an older run-time though, Vista onward come with the VC9 run-time, and if someone is using XP you can just give them the 'redistributable package' for VS2008/2010...