2011-08-12 51 views
9

我有一個項目,其中包括一些性能敏感的本機C++頭,大量使用模板。對於這個項目,我們還封裝了頭文件並添加了一些粘合代碼以將功能展示給c#和其他.NET語言。我們將這個頭文件稱爲「layout.h」,並且我們假設它是我無法更改的第三方頭文件。有沒有辦法檢測在C++/CLI中是否有效#pragma unmanaged?

在混合模式的C++/CLI程序集中,從代碼中的#pragma unmanaged(或#pramga managed(push,off))中出錯幷包含#include相對比較容易。當發生這種情況時,模板會生成IL,並且在運行代碼時會得到額外的託管/非託管轉換,性能會下降。

我的問題是我是否有辦法在#include之前執行編譯時檢查,以便編譯失敗,如果我意外#包含錯誤的上下文。

// File1.cpp, compiled in a mixed mode C++/CLI assembly with /clr 
    ASSERT_UNMANAGED() 
    #include <layout.h> 

我天真的嘗試第一次檢查的#ifdef _MANAGED,但總是被定義我無論是在代碼或不對應的#pragma非託管塊是。

+0

+1:有趣的問題。 – leppie

+0

這是一個非常艱難的。我可以想到十幾種不同的方式來實現'ASSERT_MANAGED',但'ASSERT_UNMANAGED'讓我難住了。 – ildjarn

+0

爲了防止有人查找,_MANAGED,__CLR_VER和__cplusplus_cli不受#pragma managed/#pragma ummanaged的影響,那麼範圍就是整個編譯單元。 –

回答

1

您可以編寫ASSERT_MANAGEDASSERT_UNMANAGED代碼,該代碼將使用僅在編譯託管或非託管時可用的構造。 A ref class聲明是僅在使用託管時纔可用的示例。

這有點骯髒的解決方案,但它會工作。

+1

因此,在編寫ASSERT_MANAGED()時,請引用類聲明。訣竅是找到非合法C++/CLI的合法C++來編寫ASSERT_UNMANAGED()塊 –

+2

另一個最接近的競爭對手是使用常量字符串連接,如果它工作,它是CLI代碼(System :: String),否則它是本機碼。我仍然在探索更多! – Ajay

+0

我想到void __fastcall foo();實際上並沒有工作,有點編譯器錯誤。 –

1

pragma指令必須直接插入到包含文件中。通過這種方式,無論您在何處包含文件,都會聲明非託管節。

對不起,你必須修改你的包含文件。

相關問題