Search code examples
c#.netarraysms-media-foundationsharpdx

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


I have a problem with some generic C# wrappers of non-C# code. I have stumbled upon this pattern a few times while programming in windows apis. It looks like a standard pattern ported from C/C++ (pass a pointer to an allocated array, the function then fills it with data). Only in C# there is a problem - it usually only returns the first element of such array.

// 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.

This example is from SharpDX and Media Foundation, but I've had simmilar problems with other non-related wrappers. Maybe I'm not accessing the API as I should have?

I've tried with unsafe { ... }, but it did not change a thing.


Solution

  • If you look at the documentation of MFTEnum, the parameter ppclsidMFT is declared as a out parameter while in SharpDX the signature except an input array. If you look at the generated code in SharpDX, it passes a pointer to this copy, so the generated code in SharpDX is invalid. This particular case requires custom marshaling.

    MediaFoundation in SharpDX is not a complete API and not always correctly mapped to C# due to the facts:

    1. MediaFoundation C++ headers are not well structured and they don't contain enough annotation information like Direct3D11 to produce a more reliable generated wrapper
    2. MediaFoundation is a huge API that can only be fixed on a per-usage basis. So far, MediaFoundation was only introduced in SharpDX to support MediaEngine for Windows Store/Phone Apps. The rest of the API could or could not work well.

    Feel free to fill a bug or even better, make a PR...