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

将safearray从c传递到com

  •  2
  • SlavaGu  · 技术社区  · 15 年前

    我使用第三方网站在图片中查找人脸。其中一个方法具有来自SDK的以下签名:

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

    参数:pidimage[in]-图像 搜索。

    facepositionarray[out]—数组 FacePosition2对象到哪个面 放置信息。这个数组是 在类型为的安全数组(变量)中 未知的。数组的大小 指示最大面数 要搜索的内容。

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

    int FindMultipleFaces(object pIDibImage, ref object pIFacePositions);
    

    我乐观地称之为以下方式,但得到一个例外,即内存已损坏。只有当图像中存在面时才会引发异常。

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

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

    3 回复  |  直到 15 年前
        1
  •  0
  •   Hans Olsson    15 年前

    类似于使用 Marshal.AllocCoTaskMem 然后使用 Marshal.Copy 将它复制到非托管内存中,然后 IntPtr 将数组指向COM方法。

    一般来说,看看 Marshal 班级:
    http://msdn.microsoft.com/en-gb/library/system.runtime.interopservices.marshal.aspx

        2
  •  0
  •   SlavaGu    15 年前

    哎呀,似乎我只需要初始化数组,因为faceposition2不是一个结构,而是一个类,而且它没有像我想象的那样自动初始化。这件丢失了:

    for (var i = 0; i < facePositions.Length; i++)
    {
      facePositions[i] = new FacePosition2();
    }
    
        3
  •  0
  •   Victor    15 年前

    有更复杂的方法,但观点更正确: 更改这个签名互操作,这样,他看起来像是接受一个数组。

    Accessing a SafeArray Result from a COM Call in C#

    Default Marshaling for Arrays

    Correcting Common Interop Assembly Problems