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编码,则必须手动进行封送同时转换编码。和有频繁的对同一委托进行封送调用。

      

  • 相关阅读:
    源码0603-08-掌握-NSURLSession-上传
    源码0603-05-掌握-大文件下载
    源码0603-03-掌握-NSURLSession
    源码0603-01-了解-大文件下载(NSOutputStream)
    源码0602-10-掌握-文件上传11-了解-获得文件的MIMEType
    源码0602-08-掌握-解压缩
    源码0602-06-掌握-小文件下载-大文件下载
    用JS实现的控制页面前进、后退、停止、刷新以及加入收藏等功能
    java一路走来
    CKEditor3.5.3 JAVA下使用
  • 原文地址:https://www.cnblogs.com/HansZimmer/p/10080142.html
Copyright © 2011-2022 走看看