0
votes

I've written a small Media Foundation Transform and added the C++ DLL to my C# Windows Store App project.

The 32bit version of the DLL running the x86 configuration works just fine but x64 doesn't work (it throws an Exception with the following message:

"MF_MEDIA_ENGINE_ERR_SRC_NOT_SUPPORTED : HRESULT - 0x800700C1")

If I add the 64bit version it's the same just the other way around x64 works and x86 doesn't.

Is there any way I can set it up so that it uses the x86 version of the DLL for the x86 configuration and the x64 version for the x64 configuration?

1
It is a Windows error, 0xC1 == 193 == ERROR_BAD_EXE_FORMAT. This should hardly be surprising, you really do need to build the x64 version of that DLL. Or just not bother, submitting a 32bit-only app is fine. - Hans Passant
Yeah I get that, but I don't know any way to tell VS to use the x64 version for the x64 config and the x86 version for the x86 config. I thought about changing it to 32bit only, too, but what about ARM? - Stefan Fabian
It seems like another possible way might be to create a private nuget that includes versions for all 3 platforms. However this seems to be a little overcomplicated to me and I'd be very thankful if anyone knows a better way. - Stefan Fabian
Where you specify the lib in additional libraries you could use a target architecture macro and name the dll's accordingly (my_x86.dll/lib, my_arm.dll/lib, etc.) - fassl
Not sure if that's possible though since Windows Store Apps are a little different. The dll is registered as an inProcessServer Extension in the package manifest and after reading the documentation it seems like it doesn't support placeholders. I assume NuGet might be the best option unfortunately I can't get my package to work :( - Stefan Fabian

1 Answers

0
votes

Took me some time but I figured out how to do it using NuGet. First I added a location on my PC as package source as explained here.

In VS2013 CE you do this by opening the NuGet Package Manager Settings (Tools > NuGet Package Manager > Package Manager Settings) and under Package Sources you add a location on your computer.

To create the NuGet I combined several HowTo's since one alone didn't work. The main one was this.

I built the dlls for my required platforms and created the following folder structure

Folder structure. build and lib are also folders

Since it might be a little hard to see ProjectName.props and ProjectName.targets are located in the netcore451 folder. The .dll, .pri and .winmd in lib are the x86 version. According to the HowTo it's redundant and you can just ignore these files but without them VS might not work correctly in design mode.

In the folder that contains build and lib I created a file ProjectName.nuspec

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/01/nuspec.xsd">
    <metadata minClientVersion="2.5">
        <id>ProjectName</id>
        <version>1.0.0</version>
        <authors>Stefan Fabian</authors>
        <owners>Stefan Fabian</owners>
        <requireLicenseAcceptance>false</requireLicenseAcceptance>
        <description>Description</description>
        <releaseNotes>First release.</releaseNotes>
        <copyright>Copyright 2015</copyright>
        <references>
            <group targetFramework=".NETCore4.5.1">
                <reference file="ProjectName.winmd" />
            </group>
        </references>
    </metadata>
</package>

ProjectName.props

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

</Project>

ProjectName.targets

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <Target Name="PlatformCheck" BeforeTargets="InjectReference"
    Condition=" ( ('$(Platform)' != 'x86') AND ('$(Platform)' != 'AMD64') AND ('$(Platform)' != 'Win32') AND ('$(Platform)' != 'ARM') AND  ('$(Platform)' != 'x64') )">
    <Error  Text="$(MSBuildThisFileName) does not work correctly on '$(Platform)' 
                     platform. You need to specify platform (x86 / x64 or ARM)." />
  </Target>

  <Target Name="InjectReference" BeforeTargets="ResolveAssemblyReferences">

    <ItemGroup Condition="'$(Platform)' == 'x86' or '$(Platform)' == 'Win32'">
      <Reference Include="ProjectName">
        <HintPath>$(MSBuildThisFileDirectory)x86\ProjectName.winmd</HintPath>
      </Reference>
    </ItemGroup>
    <ItemGroup Condition="'$(Platform)' == 'x64' or '$(Platform)' == 'AMD64'">
      <Reference Include="ProjectName">
        <HintPath>$(MSBuildThisFileDirectory)x64\ProjectName.winmd</HintPath>
      </Reference>
    </ItemGroup>
    <ItemGroup Condition="'$(Platform)' == 'ARM'">
      <Reference Include="ProjectName">
        <HintPath>$(MSBuildThisFileDirectory)ARM\ProjectName.winmd</HintPath>
      </Reference>
    </ItemGroup>

  </Target>
</Project>

I'm not sure if it's necessary to check for x86 and Win32 but it works for me.

Disclaimer

This was the first time ever I created a NuGet package and the code above might suck.