使用 /clr
编译代码可能会导致编译器、链接器或运行时错误。 本节讨论最常见的问题。
不同版本的数据类型可能会导致链接器失败,因为为这两种类型生成的元数据不匹配。 (当你有条件地定义类型的成员时,会发生错误,但对于使用该类型的所有 CPP 文件来说,条件并不相同。)在这种情况下,链接器将失败,仅报告符号名称和定义类型的第二个 OBJ 文件的名称。 轮换 OBJ 文件发送到链接器的顺序以发现数据类型的其他版本的位置通常很有用。
加载程序锁定死锁
“加载程序锁定死锁”可能发生,但它是确定的,会在运行时进行检测和报告。 有关详细背景信息、指导和解决方案,请参阅混合程序集的初始化。
导出 DLL 数据容易出错,不建议在 /clr
代码中这样做。 这是因为在执行 DLL 的某些托管部分之前,不能保证初始化 DLL 的数据部分。 使用 #using
指令引用元数据。
类型可见性
本机类型默认为 private
类型。 private
本机类型在 DLL 外部不可见。 将 public
添加到这些类型可以解决此问题。
浮点和对齐问题
只有公共语言运行时支持 __controlfp
。 (有关详细信息,请参阅 _control87
、_controlfp
、__control87_2
。)CLR 也不使用 align
。
公共语言运行时会在模块初始化后自动初始化 COM(当 COM 被自动初始化时,它是作为 MTA 完成的)。 因此,显式初始化 COM 会生成返回代码,指示 COM 已经过初始化。 当 CLR 已经将 COM 初始化为另一个线程模型时,尝试使用一个线程模型显式初始化 COM 可能会导致应用程序失败。
默认情况下,公共语言运行时将 COM 作为 MTA 启动;可使用 /CLRTHREADATTRIBUTE
(设置 CLR 线程属性)修改 COM 模型。
当间接调用生成到 MSIL 的本机 C++ 方法(通过虚拟函数调用或使用函数指针)时,你可能会看到性能下降。 有关详细信息,请参阅双重形式转换。
从本机迁移到 MSIL 时,你会注意到工作集的大小增加。 这是因为公共语言运行时提供了许多功能,以确保程序正常运行。 如果 /clr
应用程序未正常运行,建议启用默认关闭编译器警告(级别 1 和 3)C4793。
关闭时程序崩溃
在某些情况下,CLR 会在托管代码完成运行之前关闭。 使用 std::set_terminate
和 SIGTERM
可能会导致关闭。 有关详细信息,请参阅 signal
常量和 set_terminate
。
使用新的 Visual C++ 功能
在应用程序编译、链接和运行后,可以开始在使用 /clr
编译的任何模块中使用 .NET 功能。 有关更多信息,请参见 Component Extensions for Runtime Platforms。
有关 Visual C++ 中的 .NET 编程的详细信息,请参阅:
使用 C++/CLI (Visual C++) 进行 .NET 编程
本机和 .NET 的互操作性
适用于运行时平台的组件扩展
混合(本机和托管)程序集
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:https://aka.ms/ContentUserFeedback。
提交和查看相关反馈