2015-02-11 135 views
2

我正在爲本機C++庫編寫C++/CLI包裝。在返回給CLI包裝器的類中的一個類中,使用線程,特別是頭中的#include <mutex>來定義類級別的互斥體。本地lib中用於CLI的互斥體的解決方法

問題是一旦將頭文件帶入CLI代碼(啓用了/ clr選項),我收到編譯/ clr或/ clr:pure時不支持<mutex>的錯誤。

閱讀本文How to implement a unmanaged thread-safe collection when I get this error: <mutex> is not supported when compiling with /clr,有一篇博客文章提到了一些可能的解決方法。但是,這種解決方法假設您不需要任何會導致衝突的頭文件,並且所有這些都可以在類函數中完成,從CLI應用程序中隱藏了線程函數。

在類級別互斥體的情況下,情況並非如此。它必須在標題中。

有沒有什麼辦法讓CLI應用程序能夠與線程化的本地庫一起工作?

是的,我知道託管和非託管代碼之間的GetCurrentThreadID()問題,但是正確的方法是什麼?或者有沒有辦法解決它?

我不得不納入像ZMQ這樣的東西,因爲這是一個關鍵部分,現在有三個數據副本(這可能是非常大的)將是禁止的。 (一個在管理端,一個在本地,一個通過ZMQ中的消息緩衝區)。我知道ZMQ的零拷貝,但還沒有嘗試在託管和非託管C++之間進行處理,以查看是否可以共享內存。如果可能的話,它可能需要在整個應用程序中使用較低級別的連續數據結構,否則將遭受再次複製數據的後果。

任何嚮導都有一個體面的解決方案嗎?

+0

你可以嘗試寫你在一個單獨的.cpp文件消費類圍繞PIMPL包裝和編譯的.cpp沒有'/ clr'變型,並使用該PIMPL包裝中你的代碼的其餘部分,而不是原來的類。這種方式沒有用'/ clr'變體編譯'std :: mutex'。 – ildjarn 2015-02-11 10:07:40

+0

嗯....有趣的想法。雖然,知道GetCurrentThreadID()將在本地C++中使用是否安全?我並不想在託管和非託管之間進行線程交換,因此似乎不會出現問題。但是,其中,我不確定。 – user3072517 2015-02-11 21:06:50

+0

調用任何給定的本機函數都不是問題。問題是用'/ clr'變體編譯某些代碼。混合模式C++/CLI的一般經驗法則是使用'/ clr'儘可能地編譯_as little_代碼,只有必要的互操作位。 – ildjarn 2015-02-11 21:09:31

回答

0

我看過這個問題的std :: thread之前,我發現以下工作。由於CLR不允許在編譯時包含std::thead,因此只能在鏈接時使用它。通常情況下,你可以解決這個問題,在你的頭文件中聲明這個類,並將它們僅包含在你的cpp文件中。但你可以轉發聲明你自己的類在頭文件中,但你不能爲名稱空間標準中的類。根據C++ 11標準,17.6.4.2.1:

一個C如果除非另有規定其添加聲明或 定義以名字空間std或空間std 內的命名空間++程序是未定義的行爲。

此問題的解決方法是創建一個從std::thread,你可以向前聲明繼承的線程類。這個類的頭文件看起來像:

#pragma once 
#include <thread> 
#include <utility> 
namespace Threading 
{ 
    class Thread : std::thread 
    { 
    public: 
     template<class _Fn, class... _Args> Thread(_Fn fn, _Args... args) : std::thread(fn, std::forward<_Args...>(args...)) 
     { 

     } 
    private: 

    }; 
} 

在你想使用線程,你可以做向前聲明頭文件是這樣的:

#pragma once 

// Forward declare the thread class 
namespace Threading { class Thread; } 
class ExampleClass 
{ 
    public: 
     ExampleClass(); 
     void ThreadMethod(); 
    private: 
     Threading::Thread * _thread; 
}; 

在你的源文件就可以瞭然後使用前綴類:

#include "ExampleClass.h" 
#include "Thread.h" 

ExampleClass::ExampleClass() : 
{ 
    _thread = new Threading::Thread(&ExampleClass::ThreadMethod, this); 
} 

void ExampleClass::ThreadMethod() 
{ 
} 

你應該可以爲std :: mutex做同樣的事情。希望它可以幫助任何人。

原帖:using clr and std::thread