【问题标题】:Passing a SAFEARRAY from C# to COM将 SAFEARRAY 从 C# 传递到 COM
【发布时间】:2010-05-19 17:01:54
【问题描述】:

我使用 3rd 方 COM 在图片中查找面孔。其中一种方法具有以下签名,来自 SDK:

long FindMultipleFaces(
  IUnknown* pIDibImage,
  VARIANTARG* FacePositionArray
);

参数:pIDibImage[in] - 图片 搜索。

FacePositionArray[out]- 的数组 FacePosition2 对象进入哪个面 信息被放置。这个数组是 在类型的安全数组(VARIANT)中 VT_未知。数组的大小 规定最大面数 要搜索的内容。

转换为以下 C# 方法签名(来自元数据):

int FindMultipleFaces(object pIDibImage, ref object pIFacePositions);

乐观地说,我将其称为以下方式,但会出现内存损坏的异常。仅当图像中存在人脸时才会引发异常。

FacePosition2[] facePositions = new FacePosition2[10];
object positions = facePositions;
int faceCount = FaceLocator.FindMultipleFaces(dibImage, ref positions);

将 SAFEARRAY 传递给非托管代码的正确方法是什么?

【问题讨论】:

  • 找到问题的原因:数组必须手动初始化,因为 FacePosition2 不是结构体。哎哟。

标签: c# .net com interop


【解决方案1】:

这就像您使用Marshal.AllocCoTaskMem 初始化一个数组,然后使用Marshal.Copy 将其复制到非托管内存并将指向该数组的IntPtr 传递给COM 方法。

一般看Marshal类:
http://msdn.microsoft.com/en-gb/library/system.runtime.interopservices.marshal.aspx

【讨论】:

  • 哎呀,它似乎只需要我来初始化数组,因为 FacePosition2 不是结构而是类,它没有像我想的那样自动初始化。 FacePosition2[] facePositions = 新的 FacePosition2[10]; for (var i = 0; i
【解决方案2】:

糟糕,它似乎只需要我来初始化数组,因为 FacePosition2 不是结构而是类,它没有像我想的那样自动初始化。这件作品不见了:

for (var i = 0; i < facePositions.Length; i++)
{
  facePositions[i] = new FacePosition2();
}

【讨论】:

    【解决方案3】:

    有更复杂的方法,但意见更正确: 更改这个签名互操作,所以,他看起来像拿一个数组。

    Accessing a SafeArray Result from a COM Call in C#

    Default Marshaling for Arrays

    Correcting Common Interop Assembly Problems

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-12
      • 2013-06-16
      • 2011-10-15
      • 2010-11-02
      • 1970-01-01
      • 1970-01-01
      • 2012-08-03
      • 2023-01-04
      相关资源
      最近更新 更多