我遇到了一个奇怪的问题。我有一些代码来枚举视频输入设备,选择一个,然后获取它的IBaseFilter,以便我可以使用它。原始代码是C#和C ++的混合,DirectShow代码在C ++ DLL中。这段代码已经完美地运行了几年。最近,我决定将代码更新为64位并开始遇到问题。 C#代码使用DirectShow.NET,它与原始C ++代码直接相似。两组代码都有同样的问题。 C#代码如下。
在InitCaptureDevice()中,对FindCaptureDevice()的调用返回一个有效的设备。在这种情况下,我正在寻找具有特定名称的设备。当我点击BindToObject()调用时,我得到一个“BadImageFormatException,对内存位置的无效访问(来自HRESULT的异常:0x800703E6)”。这种情况大多数时间都会发生,但偶尔会有通话。
为了缩小这个问题,我编写了一个简单的C ++应用程序,而不是DLL或C#,它们做同样的事情,并为64位构建。这每次都能正常工作。我很难过。我无法弄清楚为什么只有C ++代码可以工作,但是C#/ C ++混合或纯C#代码会出现异常。一切都正确编译为64位执行。相机具有64位驱动程序,事实证明只有C ++的应用程序可以工作,我也使用Process Explorer验证了这一点。
任何人都可以想到我可能遗失或做错的事吗?
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;
}