zoukankan      html  css  js  c++  java
  • C#托管与C++非托管的情愫

    一:非托管 操作 托管,使用委托回调

    二:托管  操作   非托管,使用封送

      封送处理方式:

         1.内存拷贝

      2.固定内存地址

      总结如下:

      1.string类型

         把string封送到非托管函数:

               Marshal.StringToHGlobalAnsi、Marshal.StringToHGlobalAuto、Marshal.StringToHGlobalUni,之后调用Marshal.FreeHGlobal释放内存;

              从非托管函数里面取出string:

              Marshal.PtrToStringAnsi、Marshal.PtrToStringAuto、Marshal.PtrToStringUni。

           2.byte[ ](或者基础类型的数组),在封送到非托管函数时确保GC不要回收委托,需要保持引用但不需要Pinned:

           从byte[]拷贝封送到非托管函数:

              Marshal.Copy、GCHandle并指定GCHandleType.Pinned类型(其实就是固定内存直接传送byte[]的原始地址,省去了申请内存和拷贝的开销,速度更快)

             从非托管函数拷贝封送到byte[]:

             Marshal.Copy

        3.委托,在封送到非托管函数时需要确保GC不要回收委托,需要保持引用但不需要Pinned

            从delegate封送到非托管函数:

            Marshal.GetFunctionPointerForDelegate

         从非托管函数里面取出:

            Marshal.GetDelegateForFunctionPointer

        4.结构体,只能使用基础类型和固定长度的数组,并且标记StructLayout的LayoutKind.Sequential属性

      封送到非托管函数:

           Marshal.StructureToPtr

      从非托管函数里面取出:

           Marshal.PtrToStructure

       5.对象,C#的对象不能在Native中进行处理,只能保存以待之后再传回给C#调用,保存的方式为C#用GCHandle引用对象,然后把GCHandle转成IntPtr,传给Native作为指针保存。

    注意:有几种情况还是需要手动进行封送的,string的编码是utf8之类的非ansi非utf16编码,则必须手动进行封送同时转换编码。和有频繁的对同一委托进行封送调用。

      

  • 相关阅读:
    AddParent
    AddChild
    贝塞尔曲线代码
    顶点纹理shader
    抽象方法与抽象类
    Application类
    布局组件
    C#单例和Unity单例
    Unity&UGUI
    Json解析
  • 原文地址:https://www.cnblogs.com/HansZimmer/p/10080142.html
Copyright © 2011-2022 走看看