/clr 限制

请注意以下关于使用 /clr 的限制:

  • 在结构化异常处理程序中,当使用 /clr 进行编译时,使用 _alloca 存在限制。 有关详细信息,请参阅 _alloca

  • 运行时错误检查的使用对 /clr 无效。 有关详细信息,请参阅如何:使用本机运行时检查

  • /clr 用于编译仅使用标准 C++ 语法的程序时,以下准则适用于内联程序集的使用:

    • 内联程序集代码假定知道本机堆栈布局、当前函数外部的调用约定或其他有关计算机的低级别信息,如果知道的是应用于托管函数的堆栈帧,内联程序集代码可能会失败。 包含内联程序集代码的函数将生成为非托管函数,就像它们被放置在一个不使用 /clr 编译的单独模块中一样。

    • 不支持传递复制构造函数参数的函数中的内联程序集代码。

  • 无法从使用 /clr 编译的程序中调用 vprintf 函数

  • /clr 下,naked__declspec 修饰符会被忽略。

  • _set_se_translator 设置的转换器函数将仅影响非托管代码中的 catch 语句。 有关详细信息,请参阅异常处理

  • /clr 下不允许比较函数指针。

  • /clr 下不允许使用未完全原型化的函数。

  • /clr 不支持以下编译器选项:

  • 不支持 _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_argva_copyva_endva_start/clr:pure/clr:safe 编译器选项在 Visual Studio 2015 中已弃用,并且在 Visual Studio 2017 及更高版本中不受支持。 “纯”代码或“安全”代码应移植到 C#。

  • 不应调用任何遍历堆栈的函数来从托管代码中获取参数信息(函数参数)。 P/Invoke 层会导致该信息进一步向下堆栈。 例如,不要使用 /clr 编译代理/存根。

  • 如果可能,函数将被编译为托管代码,但并非所有 C++ 构造都可以转换为托管代码。 应根据函数作出决定。 如果函数的任何部分无法转换为托管代码,则整个函数将转换为本机代码。 以下情况会阻止编译器生成托管代码。

    • 编译器生成的 thunk 或 helper 函数。 通过函数指针(包括虚拟函数调用)为任何函数调用生成本机 thunk。

    • 调用 setjmplongjmp 的函数。

    • 使用某些内部例程直接处理机器资源的函数。 例如,使用 __enable__disable_ReturnAddress_AddressOfReturnAddress 或多媒体内部函数都会产生本机代码。

    • 遵循 #pragma unmanaged 指令的函数。 (也支持反转 #pragma managed。)

    • 包含对齐类型(即使用 __declspec(align(...)) 声明的类型)引用的函数。

另请参阅