LoaderLock был обнаружен, и отключение предупреждения не помогает
Я пытаюсь написать приложение, которое принимает звук со стандартного устройства записи звука на компьютере. При запуске любого кода, который обращается к DirectX из моего управляемого кода, я получаю эту ошибку:
DLL "C:\Windows\ Assembly\GAC\Microsoft.DirectX.DirectSound\1.0.2902.0__31bf3856ad364e35\Microsoft.DirectX.DirectSound.dll" пытается выполнить управляемое выполнение внутри блокировки загрузчика ОС. Не пытайтесь запускать управляемый код внутри функции инициализации DllMain или изображения, так как это может привести к зависанию приложения.
DevicesCollection coll = new DevicesCollection();
а также
Device d = new Device(DSoundHelper.DefaultCaptureDevice);
а также
Capture c = new Capture(DSoundHelper.DefaultCaptureDevice);
все это вызывает всплывающее окно LoaderLock MDA и говорит мне, что есть проблема. Я искал Интернет (включая stackru) для решения этой проблемы, но большинство людей просто говорят, чтобы отключить предупреждение, которое не работает. Когда я отключаю предупреждение, генерируется универсальное ApplicationException, что еще менее полезно. Я также видел ответы на этот вопрос, который не помог, потому что он сказал удалить код, который вызывает ошибку. Другие сказали "исправь свой код".
Мои вопросы:
Как я могу вызвать любой (желательно управляемый) код DirectX из C# без получения этой ошибки?
редактировать: это трассировка стека я получаю:
at Microsoft.DirectX.DirectSound.Device..ctor(Guid guidDev)
at Autotuner.fMain.button1_Click(Object sender, EventArgs e) in C:\\Users\\Scott\\Documents\\Visual Studio 2008\\Projects\\Autotuner\\Autotuner\\Form1.cs:line 17
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at Autotuner.Program.Main() in C:\\Users\\Scott\\Documents\\Visual Studio 2008\\Projects\\Autotuner\\Autotuner\\Program.cs:line 18
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
1 ответ
Вне управляемой среды, один из самых простых способов выполнения кода в блокировке загрузчика в C++ состоит в том, чтобы встроенные в dll классы выполняли свою инициализацию в глобальной области видимости.
Единственный раз для инициализации объектов dll - это сообщения DllMain от ОС, но во время этих сообщений блокировка загрузчика активна. блокировка загрузчика предотвращает одновременную загрузку различными библиотеками dll-файлов в DllMain одной библиотеки одновременно.
Устранить проблему довольно сложно в C++ (и, предположительно, в управляемых средах), поскольку, возможно, существует много неявных объектов, нуждающихся в построении в dll. Тем не менее, вам нужно найти код инициализации, который вызывается из DllMain, и убедиться, что он вызывается из явной инициализации / завершения работы функций dll, экспортируемых или выполняемых точно в срок.