【问题标题】:Native code in C++/CLI DLLC++/CLI DLL 中的本机代码
【发布时间】:2012-06-30 06:54:29
【问题描述】:

我希望尽可能接近实时,所以我的意图是让代码中最关键的部分不受管理(我不希望 GC 阻塞执行)。所以我尝试了这个:

class Native 
{
public:
    int GetValue() 
    {       
        return 1;
    }
};

ref class Managed 
{
public:
    void Test() 
    {
        Native n;
        Console::WriteLine(n.GetValue());
    }
};

ILDASM 显示编译为 IL 的 Native::GetValue。是否可以保持此类/功能不受管理?专用的非托管 dll 是唯一的方法吗?

【问题讨论】:

    标签: .net visual-studio-2010 c++-cli


    【解决方案1】:

    看来我需要#pragma 指令:

    #pragma unmanaged
    
    class Native 
    {
    public:
        int GetValue() 
        {       
            return 1;
        }
    };
    
    #pragma managed
    
    ref class Managed 
    {
    public:
        void Test() 
        {
            Native n;
            Console::WriteLine(n.GetValue());
        }
    };
    

    【讨论】:

      【解决方案2】:

      C++-CLI 是托管扩展,允许您直接使用 .NET 函数,例如您在示例中显示的 Console.WriteLine。它被编译成托管程序集。如果您想要非托管代码,则必须指示编译器生成非托管代码。但在这种情况下,显然您将不得不忘记 .NET 函数。

      【讨论】:

      • 其实有一种方法可以将托管代码和非托管代码合并到同一个DLL中。
      • 是的,但是生成的程序集将由 CLR 管理并因此由 CLR 处理,这是我认为您首先要避免的。这正是 C++-CLI 的用处:轻松将一些现有的本机代码移植到托管平台。
      • 正如之前所说,出于性能考虑,我只需要保持一些类/函数不受管理。
      • 然后,正如我在回答中所说,您必须指示 C++ 编译器生成本机/非托管代码。并且为了使它工作,你必须从中删除所有 .NET 函数调用,否则编译器将简单地阻塞。将代码编译到本机库后,您可以使用 P/Invoke 从托管代码中使用它。
      • 我的答案结合了 .NET 函数调用和非托管片段。如您所见,我们可以在同一个程序集中拥有所有这些。这是我的问题。抱歉,如果问题听起来模棱两可。
      【解决方案3】:

      嗯,我可能误解了你的要求,但我对此感到窒息:

      我不希望 GC 阻塞执行

      这取决于您使用的互操作方案,但通常您无法通过简单地使应用程序的某些部分不受管理来防止暂停执行线程。任何沿其调用堆栈具有 CLR 根的线程都可能被 GC 劫持和停止,无论该线程是否恰好执行“非托管”代码。

      【讨论】:

        猜你喜欢
        • 2019-10-04
        • 1970-01-01
        • 1970-01-01
        • 2021-12-03
        • 2011-08-29
        • 1970-01-01
        • 1970-01-01
        • 2013-07-25
        • 1970-01-01
        相关资源
        最近更新 更多