boost::recursive_mutex and boost::lock_guard seem to use boost_thread-bcb-mt-1_39.dll in C++ Builder 2010. I see that there is also static version - boost_thread-bcb-mt-1_39.lib.
My code is something like this:
boost::recursive_mutex mylock;
//...
boost::lock_guard<boost::recursive_mutex> lock(mylock);
However, if I set compile option to Release and set Dynamic RTL option to False all I get is Mixing a dll boost library with a static runtime is a really bad idea.... Returning Dynamic RTL to True compiles but then it needs additional DLL's - cc32100mt.dll and boost_thread-bcb-mt-1_39.dll.
Is there a way to compile it statically in a single exe? After all, LIB file is provided, it should be possible. Is it a problem with this version of C++ Builder or Boost?
What I needed was to define in a header file:
#define BOOST_THREAD_USE_LIB
right before:
#include <boost/thread/recursive_mutex.hpp>
#include <boost/thread/locks.hpp>
After then it compiles without any issues.
Related
I am trying to determine if it is possible at all to create a static library that:
Internally uses Microsoft/STL, static release runtime (/MT)
Can be linked to objects not using /MT (e.g., Dynamic DLL Release, Static Debug, etc.)
The specific test code I'm trying to get working is as follows:
Header:
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
int EncapLibConcatenate(int a, int b);
#ifdef __cplusplus
}
#endif
Source:
#include "EncapLib.h"
#include <string>
int EncapLibConcatenate(int a, int b)
{
try {
return std::stoi(std::to_string(a) + std::to_string(b));
} catch (...) {
return 0;
}
}
Linking to the above predictably results in a /FAILIFMISMATCH error when not using /MT for the project that links to the above library. I would like to learn of any compiler / linker options to circumvent this issue. If such do not exist, then any other approaches (such as modifying the .obj COFF files post-build) would also be welcome.
As a side note, I am aware that creating a dynamic library is the idiomatic approach to encapsulating library dependencies; this is a question regarding technical possibilities, not best practices. I have also been able to create a runtime-agnostic static library by eschewing any use of the standard library (restricting to C runtime and win32). This question is specifically about a static library that uses the C++ standard library internally (though pointedly not at its interface).
If you download the latest version of Google Mock (1.7.0) there are project files for VS2005 and 2010! The project to test is written in VS2008,so I opened the VS2005 file and converted it for VS2008 and compiled with
Multi-threaded Debug (/MTd)
Dynamic Library (.dll)
In the test solution:
Project to test:
Configuration type: Dynamic Library (.dll)
Runtime library: Multi-threaded Debug (/MTd)
UnitTest project:
#include <iostream>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
int main(int argc, char **argv)
{
::testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}
Additional Library Directories: ..\..\gmock\msvc\2005\Debug
Additional Dependencies: gmock.lib gmock_main.lib
Runtime library: Multi-threaded Debug (/MTd)
If I run the UnitTest project I get following error:
Windows has triggered a breakpoint in Program_UnitTests.exe.
This may be due to a corruption of the heap, which indicates a bug in Program_UnitTests.exe or any of the DLLs it has loaded.
in xmtx.c:
_RELIABILITY_CONTRACT
void __CLRCALL_PURE_OR_CDECL _Mtxunlock(_Rmtx *_Mtx)
{ /* unlock mutex */
LeaveCriticalSection(_Mtx);
#ifdef _M_CEE
System::Threading::Thread::EndThreadAffinity();
#endif
} // <------- STOPPED HERE
#endif /* !_MULTI_THREAD */
What is wrong here? Thank you for any help!
Super-short answer: compile googlemock as a static library instead of a dll; that might fix your problem.
Much longer answer:
Problems like this are typically the result of mismatched compiler settings. These kinds of problems are a pain to diagnose, which is a large part of the reason for the following guidance given in the googletest FAQ:
If you compile Google Test and your test code using different compiler flags, they may see different definitions of the same class/function/variable (e.g. due to the use of #if in Google Test). Therefore, for your sanity, we recommend to avoid installing pre-compiled Google Test libraries. Instead, each project should compile Google Test itself such that it can be sure that the same flags are used for both Google Test and the tests.
This applies equally to googlemock. Basically, they're suggesting that you compile the googletest & googlemock source code alongside your own code to avoid this problem. They also make this quite easy: check out the fused-src directory of the gmock distribution for a voltron .cc file and the corresponding headers, gmock.h and gtest.h.
If you'd like to continue linking against a completely separate library, you'll need to verify that all of the compiler settings match in the VS project. Basically you'll need to check every single configuration in the properties dialog, paying special attention to the toolset, exceptions, preprocessor definitions, RTTI, etc.
I am using visual studio 2012 with a clr library that needs to link to a native library.
My library which is using boost::future.
I am having this problem when I use future::then(F &&) function against the managed project:
Error 910 error LNK2022: metadata operation failed (8013119F) : A TypeRef exists which should, but does not, have a corresponding TypeDef: (dummy): (0x0100003e). D:\ClrProject\somefile.obj
I tried, as suggested in other questions, to make the dummy types in the library complete, since I cannot forward declare a nested struct from inside a template, as can be done with boost::thread::dummy struct.
This did not solve the problem.
My setup is the following:
Boost 1.55.
Using boost .dlls.
define BOOST_RESULT_OF_USE_DECLTYPE
define BOOST_THREAD_PROVIDES_FUTURE
define BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
I am using these very defines on the dependent .dll as well, to make sure that all parts of the API are exposed correctly.
Solved.
#Hans Passant your suggestion was right. I just wasn't putting the #pragma the correct way.
I had to put the pragmas so that my headers are compiled as unmanaged code. Once that was done, it seems that template instantiations for my code were emitted as unmanaged. At that point, problems disappeared.
So what I did is something like this:
#pragma managed(push, off)
#include "MyHeaderWithFutures.h"
#pragma managed(pop)
void f() {
//
f = myObject.Something().then(...);
}
I'm using Qt creator and the yaml-cpp library. I placed yaml-cpp under my source code directory and added it to the Qt project's include path like so:
INCLUDEPATH += Crypto \
Yaml
QMAKE_CXXFLAGS += -std=gnu++0x
DEFINES += __GXX_EXPERIMENTAL_CXX0X__
As you can see, I also told it to use C++ 11 because that is a requirement of this library. However, I get this error on compiling my project (this is the only error):
../ProjectName/Yaml/yaml-cpp/node/ptr.h:11:10: fatal error: 'boost/shared_ptr.hpp' file not found
#include <boost/shared_ptr.hpp>
^
I also tried, at the advice of some online resources, to replace it with #include <memory>, but this does not work. When I try this, it still cannot find shared_ptr.
I probably could compile the library and link Qt creator to it, but I would have to do this on every platform I use and on every machine that every project developer uses. It seems like a more elegant solution to put the source code inside my GitHub directory and compile it along with the project to minimize the overhead of someone compiling the project on their machine, particularly since this is an open source project.
Here is the source code of Yaml-Cpp's file in question:
#include "yaml-cpp/dll.h"
#include <boost/shared_ptr.hpp>
namespace YAML
{
namespace detail {
class node;
class node_ref;
class node_data;
class memory;
class memory_holder;
typedef boost::shared_ptr<node> shared_node;
typedef boost::shared_ptr<node_ref> shared_node_ref;
typedef boost::shared_ptr<node_data> shared_node_data;
typedef boost::shared_ptr<memory_holder> shared_memory_holder;
typedef boost::shared_ptr<memory> shared_memory;
}
}
It seems that you do not have boost installed. You would need to amend that first.
However, you could urge the yaml-cop developers to use the recent C++ standard more and more when their software is built using C++11 or later. C++11 is not a new thing anymore. It should be utilized as much as possible.
I'm working with VC9 on Windows.
I have a library (lets call it libfoo) which is made of the following files ("include guards" and "#include" directives omited for clarity's sake):
// foo.hpp
class Foo
{
public:
static const std::string SOME_CONST;
};
And:
// foo.cpp
#include "foo.hpp"
const std::string Foo::SOME_CONST = "hello";
Foo::SOME_CONST is exported using a .def file.
The library compiles fine: a libfoo.lib file and a libfoo.dll file are generated.
I used this library in a sample program, like:
// main.cpp
#include <foo.hpp>
int main()
{
std::cout << Foo::SOME_CONST << std::endl; // std::bad_alloc here
return EXIT_SUCCESS;
}
A std::bad_alloc is thrown whenever I attempt to use Foo::SOME_CONST.
This only happens if I link dynamically to libfoo. Linking statically results in a perfectly working program.
What could possibly be going on here ? Is it legal to export a std::string constant that way ?
Check if dll actually does dynamic initialization, because it might not, standard has no requirements for dynamic libraries. Wrapping globals in static functions can be the solution.
Use __declspec(dllexport) and __declspec(dllimport). Stop worrying about .def files and all of that rubbish- let the compiler do the work.
Are the library and the main application linking to the same version of the standard library and/or CRT and/or MFC, with exactly the same settings? I've seen allocation issues when using different versions of the CRT, and also fought bugs caused by different iterator debugging settings between a library and its including application.