zoukankan      html  css  js  c++  java
  • (C#,com)外部dll方法中的指针中的指针该如何处理?

      网上有部分文章的解决办法是利用extern关键字引用该方法,然后利用unsafecode特性来利用c++样的代码操作,如果是这样使用dll中少数几个方法还好,加入还会用到dll中的事件或者很多方法该怎么办,特别是使用com组件!

      所幸dotnet为我们提供了marshal这个类,并提供了一系列方法来给我们使用,我们可以先引用com组件(注册com组件,然后在引用的时候选择com组件页签),然后利用marshal类的方法来进行进一步操作。

      比如当前com组件提供了一个GetStructA(int id,[out] StructA** strcutA)的方法,在我们引用该组件后,vs会自动将该方法转化成GetStructA(int id,IntPtr structA)这种申明形式。调用之前,我们应该弄清楚structA变量到底是谁赋值的变量,由其申明我们可以看出strcutA是由com组件来赋值的(因为它是个out参数),因此我们在调用之前需要这样来申明

    IntPtr v = Marshal.AllocCoTaskMem(4); //Allocates a block of memory of specified size from the COM task memory allocator

      而不是

    IntPtr v = Marshal.AllocHGlobal(4);  //Allocates memory from the unmanaged memory of the process.

      然后我们就可以调用该com的方法了

    GetStructA(id1,v);

      这时候v的值也只是个地址,我们需要进行以下转换才能得到最终的structA

    关键转换代码
    1 StructA structA= new StructA();
    2 IntPtr pv = Marshal.AllocHGlobal(Marshal.SizeOf(structA));//分配非托管内存。
    3  pv =(IntPtr)Marshal.PtrToStructure(v, typeof(IntPtr)); //转换得到structA那块内存的首地址
    4  if (pv == IntPtr.Zero) return;
    5 structA= (StructA )Marshal.PtrToStructure(pv, typeof(StructA)); //转换得到真实的struct值

      最后不要忘记回收相关变量先前分配的资源

    1 Marshal.FreeCoTaskMem(v);
    2 Marshal.FreeHGlobal(pv);

      上述的structA实际上可以是结构也可以是类,不能只看PtrToStructure方法字面意思就断定该方法只能针对结构。

      另外以上言论若有错误请不吝赐教。

  • 相关阅读:
    Ant 警告:sun.misc.BASE64Decoder 是 Sun 的专用 API,可能会在未来版本中删除
    SerfJ REST
    SimpleDateFormat的线程安全问题与解决方案
    蔡勒(Zeller)公式:根据日期推算是星期几
    【转】详解 Spring 3.0 基于 Annotation 的依赖注入实现
    PostgreSQL JSON ARRAY 数据类型
    【转】Tomcat源代码阅读系列
    Spring 数据源
    IBatis-Spring 整合
    24 The Go image package go图片包:图片包的基本原理
  • 原文地址:https://www.cnblogs.com/ocean2000/p/1704200.html
Copyright © 2011-2022 走看看