如何在 C# 中访问由包装的非 .net API 返回的数组?

How to access an array returned by a wrapped non-.net API in C#?

我对一些非 C# 代码的通用 C# 包装器有疑问。我在 windows api 中编程时偶然发现了这种模式几次。它看起来像是从 C/C++ 移植的标准模式(将指针传递给分配的数组,然后函数用数据填充它)。仅在 C# 中存在问题 - 它通常只有 returns 此类数组的第一个元素。

// some setup
var category = SharpDX.MediaFoundation.TransformCategoryGuids.VideoDecoder;
var flags = SharpDX.MediaFoundation.TransformEnumFlag.Hardware | TransformEnumFlag.Localmft | TransformEnumFlag.SortAndFilter;
var typeInfo = new SharpDX.MediaFoundation.TRegisterTypeInformation();
typeInfo.GuidMajorType = MediaTypeGuids.Video;
typeInfo.GuidSubtype = VideoFormatGuids.H264;

Guid[] guids = new Guid[50];
int someRef;

// problematic line
MediaFactory.TEnum(category, (int)flags, null, null, null, guids, out someRef);

// only first guid is filled out at this point, while I know from other sources that there are more.

此示例来自 SharpDX 和 Media Foundation,但我在使用其他不相关的包装器时遇到了类似的问题。也许我没有像我应该的那样访问 API?

我试过 unsafe { ... },但没有任何改变。

如果您查看 MFTEnum 的文档,参数 ppclsidMFT 被声明为输出参数,而在 SharpDX 中,签名除了输入数组。如果您查看 SharpDX 中生成的代码,它会传递一个指向此副本的指针,因此 SharpDX 中生成的代码是无效的。这种特殊情况需要自定义封送处理。

SharpDX 中的 MediaFoundation 不是完整的 API,并且由于以下事实并不总是正确映射到 C#:

  1. MediaFoundation C++ headers 结构不佳,它们没有像 Direct3D11 那样包含足够的注释信息来生成更可靠的生成包装器
  2. MediaFoundation 是一个巨大的 API,只能在 per-usage 基础上固定。到目前为止,MediaFoundation 仅在 SharpDX 中引入以支持 Windows Store/Phone 应用程序的 MediaEngine。 API 的其余部分可以或不能很好地工作。

欢迎填写 bug or even better, make a PR...