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

将代码元素封送到C中的intptr#

  •  1
  • user142350  · 技术社区  · 15 年前

    我正在编写一个Visual Studio外接程序,需要将托管代码元素对象整理为它的未管理表单。我只需要在内存中使用指针,因为我可以对它进行强制转换,并将其视为非托管端的代码元素。

        [DllImport("CodeMethodsToString.dll")]
        private static extern BSTR* CodeMethodsToString(void* functionObject);
    
        public static void CodeMethodsToXML(XmlElement parent, CodeElements elements)
        {
            //Call CodeMethodsToString: how do I marshall CodeElements to an IntPtr?
            //set XmlElement in here
        }
    

    我知道如何处理XML,并且我有一个在C中工作的版本。我创建了非托管的dll,因为在递归的最低级别调用所有的成员变量会扼杀程序的速度。我只需要知道如何使用System.Runtime.Interop.Marshal将CodeElements对象转换为指向内存中COM对象的指针。

    谢谢。

    4 回复  |  直到 13 年前
        1
  •  3
  •   scottm    15 年前

    看来乔纳森很亲近。我就是这样做的:

    [DllImport("CodeMethodsToString.dll")]
    [return: MarshalAs(UnmanagedType.BStr)]
    private static extern string CodeMethodsToString(IntPtr functionObject);
    
    public static void CodeMethodsToXML(XmlElement parent, CodeElements elements)
    {
       GCHandle pin;
       try
       {
          pin = GcHandle.Alloc(elements, GCHandleType.Pinned);
          string methods = CodeMethodsToString(pin.AddrOfPinnedObject());
        }
        finally
        {
           pin.Free();
        }
    }
    
        2
  •  1
  •   dtb    15 年前

    CodeElements ComVisible 接口并具有 GuidAttribute ?

    然后C将为您整理COM对象,您可以简单地使用 代码元素 作为参数类型:

    [DllImport("example.dll")]
    private static extern void DoStuff(CodeElements codeElements);
    
        3
  •  1
  •   Jonathan C Dickinson    15 年前

    一旦你看到一个星或者一个符号,你就应该把它转换成REF(指针的安全版本)。我在过去使用ref关键字时,就神奇地开始使用引用类型(这是一个非常矛盾的问题,但我认为这是互操作的问题之一):

    [DllImport("example.dll")]
    private static extern void DoStuff(ref CodeElements codeElements);
    

    您也可以尝试:

    [DllImport("example.dll")]
    private static extern void DoStuff([In, Out] ref CodeElements codeElements);
    

    或者这些属性的排列之一。

    你可能想尝试的是使用MFC(我想,自从C++以来已经很长时间)来制作COM库了。不要使用本地电话, export the thing as a type library 在Visual Studio中添加它作为引用(是的,这很容易)。因此,你将得到如下的结果:

    myCoolClass.DoStuff(codeElements);
    

    您可能还想固定它(如果需要固定它,错误将是间歇性的)。我不记得 RCW 会为你做这件事(我几乎可以肯定它会),所以下面是做这件事的代码:

    GCHandle handle = new GCHandle();
    try
    {
      handle = GCHandle.Alloc(fooz, GCHandleType.Pinned);
      // Use fooz.
    }
    finally
    {
      if (handle.IsAllocated)
        handle.Free();
    }
    
        4
  •  1
  •   kaqkk    13 年前

    您可以选择在本文末尾查看示例: GCHandle MSDN