问题
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?
回答1:
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.
回答2:
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).
回答3:
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.
来源:https://stackoverflow.com/questions/5670248/boost-mutex-c-cli-problems