I'm developing in Visual Studio 2008 C# for 64bit and I want to use to use a library which uses boost. So I wrote a wrapper in C++/CLI. I managed to target the error I get to
#include <boost/thread/mutex.hpp>.
If I include any file in my C++/CLI wrapper that by itself includes <boost/thread/mutex.hpp>
or if I include it directly in the wrapper I get a "System.AccessViolationException" "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
I was very carefull in building everything for 64bit so I doubt that the problems is there. When I use the same library in 64 bit in "plain" C++ everything works fine. I came over a couple of posts where people seem to have similar problems with boost threads but none of the solutions I found worked. Does anyone have an idea?
The problem is that boost.thread uses some #pragma section
directives that are incompatible when built without /clr then statically linked to code that uses /clr.
I've heard that rebuilding boost.thread with /clr (i.e., pass cxxflags="/clr"
when invoking bjam) fixes the issue, but I haven't tried it personally.
I assume that dynamically linking to boost.thread (rather than statically, which is the default for VC++; #define BOOST_THREAD_DYN_LINK
before including any boost headers) should work too, but again, I haven't tried it.
If that doesn't work, try googling for some combination of boost
thread
clr
tls
; you should find quite a few posts on the boost mailing list about it, as this is an old problem.
EDIT: As commented here by Raman Sharma (a senior PM at Microsoft), even std::mutex
isn't supported with /clr, so it's no real surprise that boost.thread's mutex implementation isn't either.
As the other answer says, boost's pragmas in tss_pe.cpp are incompatible with the CLR. A simple modification to that file fixes the issue though and will permit static linkage. My modified version for Boost 1.44 is here (diff versus this for changes made).
Some of the Boost libraries must not be linked statically with the C++ CLI code otherwise the compiler can generate an incompatible image for some of the Windows versions.
As far as I am concerned, I had a hard time figuring out the issue when statically building with Boost 1.64 x86 thread library with VC++ 2017 under windows 10.
The binary worked fine under Windows 10 but raised a System.BadImageFormatException under Windows 7.
The issue was located in the Boost thread library which I initially statically linked to my C++ CLI assembly.
Here is a short code which easily reproduces the problem:
testcli.h - C++ CLI assembly FAILURE code
#pragma comment(lib, "libboost_thread-vc141-mt-1_64.lib") // static link makes the program crash under W7
namespace testcli
{
public ref class TestClass { public: static void Test(){} };
}
Program.cs - C# client code loading 'testcli'
using testcli;
namespace Cli
{
class Program { static void Main(string[] args) { new TestClass(); } } // instanciate C++ CLI Boost class
}
The code above returns by raising a System.BadImageFormatException (the exception can be found in the Application Event Viewer).
If testcli is changed so that the Boost thread library is now linked dynamically:
testcli.h - C++ CLI assembly SUCCESSFUL code
#pragma comment(lib, "boost_thread-vc141-mt-1_64.lib") // dynamic link works fine under any Windows
namespace testcli
{
public ref class TestClass { public: static void Test(){} };
}
The code now returns successfully.
Note that you can define BOOST_THREAD_DYN_LINK instead of BOOST_ALL_DYN_LINK as explained here: http://www.boost.org/doc/libs/1_64_0/doc/html/thread/build.html
Doing so, you will not have to package all the Boost dynamic libraries with your application.