Я сталкиваюсь со странной проблемой. У меня есть код для перечисления устройств видеовхода, выберите один, а затем получите 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;
}
Задача ещё не решена.
Других решений пока нет …