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

Posted

技术标签:

【中文标题】如何访问由 C# 中包装的非.net API 返回的数组?【英文标题】:How to access an array returned by a wrapped non-.net API in C#? 【发布时间】:2015-08-27 19:21:04 【问题描述】:

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

// 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 ... ,但它并没有改变任何事情。

【问题讨论】:

【参考方案1】:

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

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

    MediaFoundation C++ 标头结构不完善,并且它们没有像 Direct3D11 那样包含足够的注释信息来生成更可靠的生成包装器 MediaFoundation 是一个庞大的 API,只能根据使用情况进行修复。到目前为止,MediaFoundation 仅在 SharpDX 中引入,以支持 Windows 商店/电话应用程序的 MediaEngine。 API 的其余部分可以正常工作,也可以不正常工作。

请随意填写bug,或者更好的是,填写PR...

【讨论】:

以上是关于如何访问由 C# 中包装的非.net API 返回的数组?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用服务帐户通过 .NET C# 访问 Google Analytics API V3?

C#:解析对具有 x 属性的类对象的非 JSON 仅数组 api 响应

asp.net调用javascript返回值

c# .net web api webapi如何返回一个数据使浏览器弹出一个窗体?

.net中,如何在Web中使用Timer控件

C# 接口的非公共成员 [关闭]