我正在 Visual Studio 2008 C# 64 位中进行开发,我想使用一个使用 boost 的库。所以我用 C++/CLI 编写了一个包装器。我成功地定位了出现的错误:
#include <boost/thread/mutex.hpp>.
如果我在 C++/CLI 包装器中包含任何文件,而该文件本身包含
或者如果我直接将其包含在包装器中我收到“System.AccessViolationException”“尝试读取或写入受保护的内存。这通常表明其他内存已损坏。”
我在为 64 位构建一切时非常小心,所以我怀疑问题是否存在。当我在“普通”C++ 中使用 64 位相同的库时,一切正常。我看到了几篇文章,人们似乎在增强线程方面遇到了类似的问题,但我发现的解决方案都不起作用。有人有想法吗?
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?
发布评论
评论(3)
问题是 boost.thread 使用一些 #pragma section 指令,这些指令在没有 /clr 的情况下构建时不兼容,然后静态链接到使用 /clr 的代码。
我听说用 /clr 重建 boost.thread (即调用 bjam 时传递
cxxflags="/clr"
)可以解决这个问题,但我个人还没有尝试过。我认为动态链接到 boost.thread (而不是静态链接,这是 VC++ 的默认设置;在包含任何 boost 标头之前
#define BOOST_THREAD_DYN_LINK
)也应该可以工作,但同样,我还没有尝试过。如果这不起作用,请尝试在谷歌上搜索
boost
thread
clr
tls
; 的某种组合。你应该在 boost 邮件列表上找到很多关于它的帖子,因为这是一个老问题。编辑:正如评论的此处,作者 Raman Sharma(微软高级产品经理),甚至 /clr 也不支持
std::mutex
,因此 boost 并不令人意外.thread 的互斥实现也不是。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.正如另一个答案所说,tss_pe.cpp 中 boost 的编译指示与 CLR 不兼容。对该文件进行简单修改即可解决该问题,并允许静态链接。我对 Boost 1.44 的修改版本是 此处(与 这个 进行更改)。
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).
某些 Boost 库不得与 C++ CLI 代码静态链接,否则编译器可能会为某些 Windows 版本生成不兼容的映像。
就我而言,在 Windows 10 下使用 VC++ 2017 静态构建 Boost 1.64 x86 线程库时,我很难解决这个问题。
该二进制文件在 Windows 10 下运行良好,但在 Windows 7 下引发 System.BadImageFormatException。
该问题位于 Boost 线程库中,我最初将其静态链接到我的 C++ CLI 程序集。
下面是一个简短的代码,可以轻松重现该问题:
testcli.h - C++ CLI 程序集失败代码
Program.cs - C# 客户端代码加载“testcli”
上面的代码返回引发System.BadImageFormatException(可以在应用程序事件查看器中找到该异常)。
如果更改 testcli 以便动态链接 Boost 线程库:
testcli.h - C++ CLI 程序集成功代码
代码现在成功返回。
请注意,您可以定义 BOOST_THREAD_DYN_LINK 而不是 BOOST_ALL_DYN_LINK,如下所述: http://www.boost.org/doc/libs/1_64_0/doc/html/thread/build.html
这样做,您不必将所有 Boost 动态库与您的应用程序打包在一起。
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
Program.cs - C# client code loading 'testcli'
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
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.