代码之家  ›  专栏  ›  技术社区  ›  sharptooth

C++代码从C++调用CLI时如何进行编组?

  •  9
  • sharptooth  · 技术社区  · 14 年前

    根据 this question 有可能 无缝结合 使用C++/CLI的托管和非托管代码。我不太明白——不管怎样,托管和非托管之间不应该有编组吗?

    例如,我有一个内部库,它是作为一个本地C++编译的。具有已发布标头的dll和从InnerLibrary调用代码的C++/CLI外部库。会有编组吗?谁来实施它,成本有多高?

    6 回复  |  直到 7 年前
        1
  •  6
  •   Hans Passant    14 年前

    这是一个内置在C++/CLI编译器中的特性,叫做C++互操作。你可能会想,其中涉及的黑魔法要少得多。JIT编译器生成与C++编译器生成的完全相同的机器代码。所有这些。NET值类型在C++中具有直接等价性,因此不需要转换。的确如此 自动处理引用类型,你必须自己做。引脚ptr<>,典型的

    所有这些 真正地 does是注入一段代码,处理从托管堆栈框架到非托管堆栈框架的转换。该代码在堆栈上放置一个特殊的“cookie”,由垃圾收集器识别。这可以防止它误入非托管框架,并将非托管指针错误地标识为对象引用。这段代码并不多,在发布版本中大约需要5纳秒的时间。

        2
  •  3
  •   Tim Robinson    14 年前

    不必进行任何编组,因为C++/CLI能够发出直接进行调用的不安全代码。看看Reflector中的一些C++/CLI代码——它看起来与C#非常不同。

    这是C#做不到的(至少,没有 unsafe 关键字和一些指针攻击),这也是纯模式C++/CLI无法做到的(与C#的原因相同)。

    .NET不安全代码能够直接调用非托管函数;只是,除了通过C++/CLI之外,这种功能并不方便使用。

        3
  •  3
  •   Abel    14 年前

    封送处理是将非托管数据或调用带到托管世界的过程。可以说,它只是在两者之间进行了翻译。

    使用C++/CLI,您可以混合搭配。这意味着,如果您直接使用库,请使用*。H文件,使用传统的C++代码,它将是非托管的,不需要封送处理。如果您使用BCL类或您自己的托管代码访问该数据,您可以手动添加封送层,但仅在需要时添加。例如,a LPTSTR 将需要转换为托管字符串才能用作托管字符串。使用C++ + CLI,您可以跳过这一步,并坚持传统C++代码,创建更快更宽松的代码,但代价是不使用安全的、选中的托管代码。

        4
  •  2
  •   JoeG    14 年前

    其中涉及编组,但您(即程序员)必须明确地执行编组。

    如果您的C++CLI OuterLibrary调用的函数 System.String / System::String^ C++类型系统要求在将类型传递传递到需要接受的函数的函数库函数之前执行类型转换。 const char* .你必须自己做转换-这就是编组。

    微软推出了一款名为 C++ Support Library ,它提供了帮助C++和L&;gt;C++CLI交互。

        5
  •  0
  •   Ben Voigt    14 年前

    这取决于所涉及的数据类型。

    固有类型,例如 int , double ,等等( string (不符合条件)在本机代码和托管代码中具有相同的表示形式,不需要封送处理。内部类型的数组也以同样的方式排列(如果我们忽略元数据.NET存储,但这与数组内容是分开的)。

    使用显式布局属性的值类型(其中所有成员都是内在类型)也与内存布局兼容。

    如果数据存储在托管堆上的对象中,则可能需要固定(对于所有阵列都是如此)。

    另一方面,类类型必须来回转换/翻译。

        6
  •  0
  •   Alex F    14 年前

    这里有两点:

    1) 托管/非托管代码转换:每个转换都有其固定成本。当C++/CLI代码在单个程序集中编译时,编译器会尽可能地管理所有代码,以最小化此类转换。当从C++/CLI代码调用外部非托管Dll时,这种优化是不可能的。因此,将这种转换最小化是一个好主意,至少在时间关键的部分。更多信息请参见此处: http://msdn.microsoft.com/en-us/magazine/dd315414.aspx ,性能和互操作边界的位置

    2) 参数编组。这取决于参数类型。有些参数不需要封送,例如,应该封送int.Strings之类的简单类型。一些技巧,比如固定指针,可以防止简单的类型数组编组。