【问题标题】:C++ CLI Correct way to use #pragma managed / unmanagedC++ CLI 正确使用#pragma managed / unmanaged
【发布时间】:2013-08-03 20:54:54
【问题描述】:

我正在编写一个 C++/CLI 应用程序,但我希望我的 C++ DLL 中的大部分代码能够本地运行(即不受管理)。

我在模块中只有一个 CLI 类,其他文件都是原生 C++。

那么,确保这些本地类运行的最佳方法是什么……嗯,本地运行?

我应该:

  • A) 将#pragma unmanaged 添加到每个原生类的顶部
  • B) 只需在我的单个 CLI 类中的 include 之前添加 #pragma unmanaged
  • C) 还有别的吗?

谢谢

【问题讨论】:

    标签: c++-cli


    【解决方案1】:

    我这样做的通常方法是将本机代码放入不支持 .NET 的静态库项目中(编译时不使用 /clr)。您可以为 C++/CLI 项目中的单个文件关闭 /clr,但随后预编译的头文件会变得非常混乱。使用单独的库项目,很容易为原生代码创建一个原生 pch,为托管代码创建一个托管 pch。

    然后我将我的 C++/CLI 代码与本机 C++ .lib 链接以创建 DLL。您只需设置项目依赖项,其余的由 Visual Studio 处理。

    如果您绝对必须在同一个编译单元中组合本机代码和托管代码,您也可以使用#pragma managed(push, off)#pragma managed(pop)。但是通常头文件中的任何代码都在那里,因为您打算将其内联...这意味着当包含到托管 CU 中时它应该处于托管模式,因此可以内联到托管函数中。


    尽管他的 cmets 诋毁了这个答案,Hans has begun recommending my approach

    【讨论】:

    • @Hans:从您的评论中,我只能假设您实际上并没有采用答案中推荐的方法。而且您没有完全阅读我的答案,因为我也提供了该解决方案,并指出了它导致的预编译头文件问题。
    • 我也首先尝试了 Hans 的方法,但后来遇到了 PCH 问题——我现在已经将原生内容拆分为静态库,它的工作原理就像一个魅力。 (另外,恕我直言,更干净,因为没有特定于文件的设置,只有项目范围的设置。)
    • #pragma tip 在我的情况下成功了。包含非托管头文件是不可避免的。用#pragma push/pop 包装这个包含对我来说是一个快速而干净的解决方案。
    【解决方案2】:

    您不必费尽心思来确保这一点。编译器只会在打开 /clr 选项编译您的程序时发出 IL。它看起来像一个项目选项,但实际上不是。

    只需选择包含本机代码的 .cpp 文件。通过按住 Ctrl 键并单击资源管理器窗口中的文件来选择其中多个。右键单击 + 属性、C/C++、常规。将“公共语言运行时支持”设置更改为“否...”。

    【讨论】:

    • 如果您要为此提供分步说明,最好还包括关闭对这些 CU 的预编译头文件的使用。因为 pch 将在内部使用托管代码创建,如果在没有 /clr 的情况下运行并看到该 pch,编译器将中止。
    • 这种方法是最简单的,但@BenVoigt 是正确的。我必须将预编译的标头用法更改为 /Yc 而不是 /Yu 才能编译。不过,我还没有用 ildasm 查看结果。
    【解决方案3】:

    #pragma managed(push, off)#pragma managed(pop) 包围#includes 的非托管代码。

    不适用于托管代码。

    例子:

    #include "MyManagedClass.h"
    
    #pragma managed(push, off)
    #include <string>
    #include <vector>
    #pragma managed(pop)
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-30
    • 1970-01-01
    • 1970-01-01
    • 2021-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-18
    相关资源
    最近更新 更多