2011-04-14 114 views
12

我正在开发Visual Studio 2008 C#for 64bit,我想用它来使用一个使用boost的库。所以我在C++/CLI中编写了一个包装器。我设法目标我去boost mutex C++/CLI问题

#include <boost/thread/mutex.hpp>. 

错误。如果我包括在我的C任何文件++/CLI的包装,其本身包括<boost/thread/mutex.hpp>,或者如果我直接将其包含在包装我得到一个“System.AccessViolationException”“试图读取或写入受保护的内存,这通常表示其他内存已损坏。“

我非常在意为64位构建所有东西,所以我怀疑问题出在那里。当我在“普通”C++中使用64位相同的库时,一切正常。我来了几个帖子,其中人们似乎有与助推线程类似的问题,但没有我找到的解决方案工作。有人有想法吗?

+0

你的意思是'boost :: asio'由一个库使用'boost :: thread'吗?无论如何,一旦我确实想使用'boost :: asio',并最终在我的本地小库中以winsock结尾,并被C++/Cli包装。我很抱歉,'boost'不是直接与C++/Cli联系的合适的库。尽量避免它。 – 2011-04-14 22:22:25

回答

8

问题是,boost.thread使用某些#pragma section指令,这些指令在构建时没有/ clr时不兼容,而是静态链接到使用/ clr的代码。

我听说用/ clr重建boost.thread(即调用bjam时通过cxxflags="/clr")可以解决问题,但我没有亲自尝试过。

我假设动态链接到boost.thread(而不是静态的,这是VC++的默认值; #define BOOST_THREAD_DYN_LINK在包含任何提升标头之前)应该可以工作,但是我还没有尝试过。

如果这样不起作用,请尝试使用Google搜索boost的一些组合threadclrtls;你应该在boost邮件列表中找到相当多的帖子,因为这是旧的问题。


编辑:由于拉曼夏尔马(微软高级PM)评论here,甚至std::mutex不使用/ clr支持的,所以它是没有真正的惊喜,boost.thread的互斥的实施不是非此即彼。

2

正如其他答案所述,tss_pe.cpp中的boost的编译指示与CLR不兼容。对该文件进行简单的修改可以修复问题,并允许静态链接。我对Boost 1.44的修改版本是here(针对更改所做的差异与this)。

0

某些Boost库不能与C++ CLI代码静态链接,否则编译器可能会为某些Windows版本生成不兼容的映像。 就我而言,当我在Windows 10下使用VC++ 2017静态构建Boost 1.64 x86线程库时,我很困难。 在Windows 10下,二进制工作正常但提出了System.BadImageFormatException Windows 7. 该问题位于Boost线程库中,我最初静态链接到我的C++ CLI程序集。

这里是一个短码来容易地重新产生问题:

TESTCLI。ħ - C++ CLI装配故障代码

#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#客户端代码加载 'TESTCLI'

using testcli; 

namespace Cli 
{ 
    class Program { static void Main(string[] args) { new TestClass(); } } // instanciate C++ CLI Boost class 
} 

通过提高System.BadImageFormatException上述返回的代码(异常可以在应用程序事件查看器中找到)。

如果TESTCLI被改变,使得升压线程库现在动态链接:

testcli.h - C++ CLI组件成功代码

#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(){} }; 
} 

代码现在成功返回。

注意这里解释说,你可以定义的,而不是BOOST_ALL_DYN_LINK BOOST_THREAD_DYN_LINK:http://www.boost.org/doc/libs/1_64_0/doc/html/thread/build.html

这样做,你就不必包装所有您的应用程序加速动态库。