2017-08-24 42 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

该代码旨在用作“库”,因此检测当前模式并共享代码库会更可取。 对不起,听到这是不可能的;尽管不完全出乎意料。 –

相关问题