What's causing pMoniker->BindToObject to return 800703E6 (Invalid access to memory location)?

0

I'm running into a strange problem. I have some code to enumerate Video Input devices, choose one, then get the IBaseFilter for it so I can use it. The original code was a mix of C# and C++, with the DirectShow code in a C++ DLL. This code has worked perfectly fine for a few years. Recently, I decided to update the code to 64-bit and started running into problems. The C# code uses DirectShow.NET, and is a direct analogue to the original C++ code. Both sets of code have the same problem. C# code is below.

In InitCaptureDevice(), the call to FindCaptureDevice() returns a valid device. I'm searching for a device with a particular name in this case. When I hit the BindToObject() call, I get an "BadImageFormatException, Invalid access to memory location (Exception from HRESULT: 0x800703E6)". This happens most of the time, but occasionally, the call succeeds.

To narrow down the problem, I wrote a simple C++ app, not DLLs or C#, that does the same thing, and built for 64-bit. This works correctly every time. I'm stumped. I can't figure out why the C++ only code works, but the C#/C++ mix or the pure C# code gets an exception. Everything is correctly compiled for 64-bit execution. The camera has 64-bit drivers, as evidenced by the fact that the C++ only app works, and I also verified this using Process Explorer.

Can anyone think of anything I might be missing or doing wrong?

public static DsDevice FindCaptureDevice( string deviceNameToFind )
{
  DsDevice[] capDevices;

  capDevices = DsDevice.GetDevicesOfCat( FilterCategory.VideoInputDevice );

  if ( capDevices.Length == 0 )
    throw new Exception( "No DirectShow video input drivers were found." );

  // we found 1 or more devices -- scan the list for the one we want
  if ( string.IsNullOrEmpty( deviceNameToFind ))
    return null;

  for ( int i = 0; i < capDevices.Length; i++ )
  {
    // found specified device? 
    if ( capDevices[i].Name.Contains( deviceNameToFind ))
    {
        string monikerDisplayName = String.Empty;
        try
        {
            capDevices[i].Mon.GetDisplayName( null, null, out monikerDisplayName );
            return( capDevices[i] );
        }
        catch
        {
        }
        // skip further searching since caller is looking for a specific device
        break;
    }
  }
  return( null );
}

InitCaptureDevice()
{
  DsDevice captureDev = null;

  try
  {
    captureDev = FindCaptureDevice( deviceName );
  }
  catch
  {
    captureDev = null;
  }
  if ( captureDev == null )
    return false;

  // Bind Moniker to a filter object
  Guid iid = typeof( IBaseFilter ).GUID;
  object source;
  captureDev.Mon.BindToObject( null, null, ref iid, out source );
  IBaseFilter devFilter = (IBaseFilter) source;
}
c#
c++
com
capture
directshow.net
asked on Stack Overflow Jan 16, 2014 by WarnerYoung

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0