2017-08-24 41 views
0

通常,當cl.exe使用/ clr開關編譯代碼時,它將被編譯爲MSIL以由CLR運行。但是,完全可以使用#pragma unmanaged指令創建混合模式程序集,其中包含本機代碼。如何確定C++/CLI中的當前編譯目標?

我有一些代碼行,當我爲CLR編譯併爲本機平臺編譯時,我想表現得有點不同。我已經檢查了this page上預定義的預處理器宏,但是,遺憾的是,我無法找到能夠告訴它在使用時是否正在編譯當前位代碼的MSIL或本地體系結構。我想要什麼,基本上是

#if defined(IS_THIS_MANAGED_NOW) 
#define THROW throw gcnew System::Exception("Fancy managed exception"); 
#else 
#define THROW throw "Not-so-fancy native string"; 
#endif 

#if defined(IS_THIS_MANAGED_NOW) 
#define BSR(value, result) result = BitScanReverseManagedImpl(value) 
#else 
#define BSR(value, result) _BitScanReverse(&result, value); 
#endif 

基於當前編譯目標才能正常工作。 (請注意,這些都只是爲了說明問題,而不是活代碼示例的例子。)

編輯:

下面的程序

void print(void); 

int main(int argc, char *argv[]) 
{ 
    print(); 

    return 0; 
} 

#pragma unmanaged 
#include <cstdio> 

void print() 
{ 
    std::printf("__CLR_VER = %d\n", __CLR_VER); 
    std::printf("__cplusplus_cli = %d\n", __cplusplus_cli); 
    std::printf("_MANAGED = %d\n", _MANAGED); 
} 

表明,如果與使用這些#define S保持存儲在效果/即使該函數正在爲本機目標編譯也是如此。

+0

您只會得到一個預處理器符號,告訴您/ clr有效。當你用#pragma來回切換時,你需要跟蹤。相當神祕的是,這將是一個順便說一句的問題,#pragma永遠不會離開,也永遠不會從天而降。在源代碼文件之間分割代碼是另一個明顯的方法,/ clr選項單獨應用於每個源代碼文件。 –

+0

避免定義。您的BSR示例可以輕鬆使用使用特定類型的函數。 – xMRi

回答

0

據我所知,根據#pragma指令,不可能有#ifdef#ifdef在編譯的預處理器階段期間處理,這是編譯器在稍後階段處理#pragma指令之前處理的。

最接近的是使用#ifdef __cplusplus。這將切換文件的編譯方式(帶或不帶/clr標誌),而不是#pragma。根據您的項目設置方式,這可能足夠精細,因爲您可以根據每個文件更改該設置。

#ifdef __cplusplus_cli 
#define THROW throw gcnew System::Exception("Fancy managed exception"); 
#else 
#define THROW throw "Not-so-fancy native string"; 
#endif 
+0

這似乎沒有回答這個問題,因爲即使在#pragma非託管指令之後__cplusplus_cli仍然有效(已定義)。 –

+0

如果你想'#ifdef'來反映#pragma managed/unmanaged的結果,我不認爲這是可能的。 '#ifdef'在預處理步驟中處理,'#pragma unmanaged'是代碼生成步驟。除此之外,如果您在代碼中使用'#pragma managed'和'#pragma unmanaged',爲什麼不能同時定義'#define IS_THIS_MANAGED_NOW'和'#undef IS_THIS_MANAGED_NOW'? –

+0

該代碼旨在用作「庫」,因此檢測當前模式並共享代碼庫會更可取。 對不起,聽到這是不可能的;儘管不完全出乎意料。 –

相關問題