在C#中将CodeElements编组到IntPtr

时间:2009-08-19 19:46:22

标签: c# c++ com marshalling com-interop

我正在编写一个Visual Studio,并且需要将托管的CodeElements对象编组为它的无人形式。我只需要内存中的指针,因为我可以将其转换为非托管端的CodeElement。

    [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 个答案:

答案 0 :(得分:3)

看起来Jonathan很亲密。我就是这样做的:

[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();
    }
}

答案 1 :(得分:1)

CodeElementsComVisible界面并且有GuidAttribute

然后C#将为您完成COM对象的编组,您只需使用CodeElements作为参数类型:

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

答案 2 :(得分:1)

只要看到星号或&符号,就应该将其转换为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();
}

答案 3 :(得分:1)

您可以选择查看文章末尾的示例: GCHandle MSDN