1

我正在编写一个 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

4 回答 4

3

看起来乔纳森很接近。这就是我的做法:

[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();
    }
}
于 2009-08-27T15:22:55.820 回答
1

CodeElements一个ComVisible接口并且有一个GuidAttribute?

然后 C# 将为您进行 COM 对象的编组,您可以简单地将CodeElements其用作参数类型:

[DllImport("example.dll")]
private static extern void DoStuff(CodeElements codeElements);
于 2009-08-19T23:56:35.410 回答
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 库。不要使用本机调用,将事物导出为类型库并将其添加为 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();
}
于 2009-08-24T12:30:33.450 回答
1

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

于 2012-01-09T17:33:59.227 回答