请注意以下关于使用 /clr 的限制:
在结构化异常处理程序中,当使用
/clr进行编译时,使用_alloca存在限制。 有关详细信息,请参阅_alloca。运行时错误检查的使用对
/clr无效。 有关详细信息,请参阅如何:使用本机运行时检查。当
/clr用于编译仅使用标准 C++ 语法的程序时,以下准则适用于内联程序集的使用:内联程序集代码假定知道本机堆栈布局、当前函数外部的调用约定或其他有关计算机的低级别信息,如果知道的是应用于托管函数的堆栈帧,内联程序集代码可能会失败。 包含内联程序集代码的函数将生成为非托管函数,就像它们被放置在一个不使用
/clr编译的单独模块中一样。不支持传递复制构造函数参数的函数中的内联程序集代码。
无法从使用
/clr编译的程序中调用vprintf函数。修饰
naked__declspec符在/clr..由
_set_se_translator设置的转换器函数将仅影响非托管代码中的 catch 语句。 有关详细信息,请参阅异常处理。在
/clr下不允许比较函数指针。在
/clr下不允许使用未完全原型化的函数。/clr不支持以下编译器选项:/EHsc和/EHs(/clr表示/EHa(请参阅/EH(异常处理模型))/fp:strict和/fp:except(请参阅/fp(指定浮点行为))
不支持
_STATIC_CPPLIB预处理器定义 (/D_STATIC_CPPLIB) 和/clr编译器选项的组合。 这是因为定义会导致应用程序与静态多线程 C++ 标准库链接,此行为不受支持。 有关详细信息,请参阅/MD、/MT、/LD(使用运行时库)。将
/Zi与/clr一起使用时,性能有影响。 有关详细信息,请参阅/Zi。在不指定
/Zc:wchar_t或不将字符强制转换为_wchar_t的情况下,将宽字符传递给 .NET Framework 输出例程会导致输出显示为unsigned short int。 例如:Console::WriteLine(L' ') // Will output 32. Console::WriteLine((__wchar_t)L' ') // Will output a space./GS在使用/clr编译时被忽略,除非函数位于#pragma unmanaged下或者函数必须编译为本机,在这种情况下,编译器将生成警告 C4793,该警告默认关闭。有关托管应用程序的函数签名要求,请参阅
/ENTRY。使用
/openmp和/clr编译的应用程序只能在单个 appdomain 进程中运行。 有关详细信息,请参阅/openmp(启用 OpenMP 2.0 支持)。采用可变数量参数 (varargs) 的函数将作为本机函数生成。 变量参数位置中的任何托管数据类型都将被封送到本机类型。 请注意,任何 System.String 类型实际上是宽字符字符串,但其被封送到单字节字符串。 因此,如果
printf说明符是%S(wchar_t*),它将被封送到%s字符串。在使用
va_arg宏时,使用/clr:pure编译可能会得到意外的结果。 有关详细信息,请参阅va_arg、va_copy、va_end、va_start。/clr:pure和/clr:safe编译器选项在 Visual Studio 2015 中已弃用,并且在 Visual Studio 2017 及更高版本中不受支持。 “纯”代码或“安全”代码应移植到 C#。不应调用任何遍历堆栈的函数来从托管代码中获取参数信息(函数参数)。 P/Invoke 层会导致该信息进一步向下堆栈。 例如,不要使用
/clr编译代理/存根。如果可能,函数将被编译为托管代码,但并非所有 C++ 构造都可以转换为托管代码。 应根据函数作出决定。 如果函数的任何部分无法转换为托管代码,则整个函数将转换为本机代码。 以下情况会阻止编译器生成托管代码。
编译器生成的 thunk 或 helper 函数。 通过函数指针(包括虚拟函数调用)为任何函数调用生成本机 thunk。
调用
setjmp或longjmp的函数。使用某些内部例程直接处理机器资源的函数。 例如,使用
__enable和__disable、_ReturnAddress和_AddressOfReturnAddress或多媒体内部函数都会产生本机代码。遵循
#pragma unmanaged指令的函数。 (也支持反转#pragma managed。)包含对齐类型(即使用
__declspec(align(...))声明的类型)引用的函数。