Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将代码元素编组到C中的IntPtr#_C#_C++_Com_Marshalling_Com Interop - Fatal编程技术网

C# 将代码元素编组到C中的IntPtr#

C# 将代码元素编组到C中的IntPtr#,c#,c++,com,marshalling,com-interop,C#,C++,Com,Marshalling,Com Interop,我正在编写一个VisualStudio外接程序,需要将托管CodeElements对象打包到它的非托管表单中。我只需要将指针放在内存中,因为我可以将它转换为非托管端的代码元素 [DllImport("CodeMethodsToString.dll")] private static extern BSTR* CodeMethodsToString(void* functionObject); public static void CodeMethodsToXML(Xml

我正在编写一个VisualStudio外接程序,需要将托管CodeElements对象打包到它的非托管表单中。我只需要将指针放在内存中,因为我可以将它转换为非托管端的代码元素

    [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对象的指针


谢谢。

codelements
一个
ComVisible
界面,并且有一个
guidaAttribute

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

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

codelements
是一个
ComVisible
界面,并且有一个
guidaAttribute

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

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

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

您也可以尝试:

[DllImport("example.dll")]
private static extern void DoStuff([In, Out] ref CodeElements codeElements);
或者这些属性的一种排列

您可能想尝试的一件事是使用MFC(我认为,从C++开始已经很长时间了)来创建COM库。不要使用本机调用,将其添加为VisualStudio中的引用(是的,很简单)。因此,您将得到如下结果:

myCoolClass.DoStuff(codeElements);
您可能还想固定它(如果需要固定它,错误将是间歇性的)。我不记得是否会为您这样做(我几乎可以肯定它会这样做),因此下面是执行此操作的代码:

GCHandle handle = new GCHandle();
try
{
  handle = GCHandle.Alloc(fooz, GCHandleType.Pinned);
  // Use fooz.
}
finally
{
  if (handle.IsAllocated)
    handle.Free();
}

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

您也可以尝试:

[DllImport("example.dll")]
private static extern void DoStuff([In, Out] ref CodeElements codeElements);
或者这些属性的一种排列

您可能想尝试的一件事是使用MFC(我认为,从C++开始已经很长时间了)来创建COM库。不要使用本机调用,将其添加为VisualStudio中的引用(是的,很简单)。因此,您将得到如下结果:

myCoolClass.DoStuff(codeElements);
您可能还想固定它(如果需要固定它,错误将是间歇性的)。我不记得是否会为您这样做(我几乎可以肯定它会这样做),因此下面是执行此操作的代码:

GCHandle handle = new GCHandle();
try
{
  handle = GCHandle.Alloc(fooz, GCHandleType.Pinned);
  // Use fooz.
}
finally
{
  if (handle.IsAllocated)
    handle.Free();
}

看起来乔纳森很接近。我会这样做:

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

看起来乔纳森很接近。我会这样做:

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

您可以选择查看本文末尾的示例:

您可以选择查看本文末尾的示例:

恐怕没那么简单:代码元素是抽象的。我需要一个指向该对象的指针。我该如何得到它呢?澄清一下:当它进行默认编组时,它是通过值传递的吗?有没有办法让它这样做?这是一种编组魔法,但只传递一个指针?它是通过引用传递的。我假设“CodeElements”指的是这个:所以我的示例应该可以工作。如果没有,请发布错误详细信息。肯定存在错误,但我非常感谢后续操作:存在System.AccessViolation,试图读取或写入受保护内存。我正在做你在C代码中写的东西,在C++方面(这就是让我困惑的)我有DECL BSTR* CODEMETHODSTROSTRON(EnvdTe::代码元素和CaseObjor);其中DECL是dllexport的mcro。无论如何,它对点的处理是错误的(因为类是抽象的,我不能简单地通过值传递)。为什么
&classObject
而不是
*classObject
?恐怕不是那么简单:codelements是抽象的。我需要一个指向该对象的指针。我该如何得到它呢?澄清一下:当它进行默认编组时,它是通过值传递的吗?有没有办法让它这样做?这是一种编组魔法,但只传递一个指针?它是通过引用传递的。我假设“CodeElements”指的是这个:所以我的示例应该可以工作。如果没有,请发布错误详细信息。肯定存在错误,但我非常感谢后续操作:存在System.AccessViolation,试图读取或写入受保护内存。我正在做你在C代码中写的东西,在C++方面(这就是让我困惑的)我有DECL BSTR* CODEMETHODSTROSTRON(EnvdTe::代码元素和CaseObjor);其中DECL是dllexport的mcro。在任何情况下,它对点的处理都是错误的(因为类是抽象的,我不能简单地按值传递)。为什么
&classObject
而不是
*classObject
?DTB似乎接近答案,但它似乎没有正确地编组指针。Get object reference未设置为对象的实例或受保护的内存错误,仍然需要使用封送来更改某些内容。DTB似乎接近答案,但它似乎没有正确封送指针。Get object reference未设置为对象的实例或受保护的内存错误,仍然需要通过编组更改某些内容。
ref
用于通过引用而不是通过值传递值类型(例如
struct
CodeElements
是一个COM接口,即引用类型,因此总是通过引用传递。我尝试了这个方法,但它不起作用,它可能在我正在进行的其他编组的某些组合中起作用。谢谢你提醒我这些关键字中有一个可能是相关的。@dtb-read!它说它在过去已经做出了改变;即使看起来不应该这样-生成的MSIL不完全相同,互操作层可能会认为关键字是相关的。在纯.Net到.Net的调用中