Подтвердить что ты не робот

Повысить проблемы с Mutex С++/CLI

Я разрабатываю Visual Studio 2008 С# для 64-битного, и я хочу использовать библиотеку, которая использует boost. Поэтому я написал обертку в С++/CLI. Мне удалось настроить таргетинг на ошибку, которую я получаю

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

Если я включаю какой-либо файл в свою оболочку С++/CLI, который сам по себе включает <boost/thread/mutex.hpp>, или если я включаю его непосредственно в оболочку, я получаю "System.AccessViolationException" "Попытка читать или записывать защищенную память. указание на то, что другая память повреждена."

Я был очень осторожен в создании всего для 64-битного, поэтому я сомневаюсь, что проблемы есть. Когда я использую одну и ту же библиотеку в 64 бит на "простом" С++, все работает отлично. Я столкнулся с несколькими сообщениями, в которых люди, похоже, сталкиваются с подобными проблемами с повышающими потоками, но ни одно из решений, которые я нашел, не работал. У кого-нибудь есть идея?

4b9b3361

Ответ 1

Проблема заключается в том, что boost.thread использует некоторые директивы #pragma section, которые несовместимы при построении без /clr, а затем статически связаны с кодом, использующим /clr.

Я слышал, что перестройка boost.thread с /clr (т.е. pass cxxflags="/clr" при вызове bjam) исправляет проблему, но я не пробовал ее лично.

Я предполагаю, что динамическая привязка к boost.thread(а не статически, которая по умолчанию для VС++; #define BOOST_THREAD_DYN_LINK, прежде чем включать любые заголовки форматирования) тоже должна работать, но я еще не пробовал.

Если это не сработает, попробуйте googling для некоторой комбинации boost thread clr tls; вы должны найти немало сообщений об этом в списке рассылки, так как это проблема old.


РЕДАКТИРОВАТЬ: как прокомментировал здесь от Рамана Шармы (старший премьер-министр Microsoft), даже std::mutex isn 't поддерживается с помощью /clr, поэтому не удивительно, что реализация boost.thread mutex тоже не является.

Ответ 2

Как говорится в другом ответе, усиление прагм в tss_pe.cpp несовместимо с CLR. Простая модификация этого файла исправляет проблему, хотя и позволит устанавливать статическую связь. Моя измененная версия для Boost 1.44 здесь (diff versa this для внесенных изменений).

Ответ 3

Некоторые из библиотек Boost не должны быть связаны статически с кодом CLI С++, иначе компилятор может создать несовместимое изображение для некоторых версий Windows. Насколько мне известно, мне было сложно выяснить проблему при статическом построении с помощью библиотеки потоков Boost 1.64 x86 с VС++ 2017 под окнами 10. Двоичный файл отлично работал под Windows 10, но в Windows 7 появился System.BadImageFormatException. Проблема была обнаружена в библиотеке потоков Boost, которую я изначально статически связал с моей сборкой CLI CLI.

Вот короткий код, который легко воспроизводит проблему:

testcli.h - сборка С++ CLI Код FAILURE

#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 - загрузка кода клиента С# 'testcli'

using testcli;

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

Приведенный выше код возвращает значение System.BadImageFormatException (исключение можно найти в средстве просмотра событий приложения).

Если testcli изменен так, что библиотека потока Boost теперь связана динамически:

testcli.h - сборка С++ 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_THREAD_DYN_LINK вместо BOOST_ALL_DYN_LINK, как описано здесь: http://www.boost.org/doc/libs/1_64_0/doc/html/thread/build.html

Для этого вам не придется упаковывать все динамические библиотеки Boost с вашим приложением.