LoaderLock был обнаружен, и отключение предупреждения не работает - PullRequest
1 голос
/ 02 апреля 2010

Я пытаюсь написать приложение, которое принимает звук с устройства записи звука по умолчанию на компьютере. При запуске любого кода, который обращается к 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 и говорит мне, что есть проблема. Я искал в Интернете (включая stackoverflow) для решения этой проблемы, но большинство людей просто говорят, чтобы отключить предупреждение, которое не работает. Когда я отключаю предупреждение, генерируется универсальное ApplicationException, что еще менее полезно. Я также видел ответы на на этот вопрос , что не помогло, потому что он сказал удалить код, вызывающий ошибку. Другие говорили: «исправь свой код».

Мои вопросы:

как я могу вызвать любой (предпочтительно управляемый) код DirectX из C # без получения этой ошибки?

edit: это трассировка стека, которую я получаю:

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 Ответ

2 голосов
/ 02 апреля 2010

За пределами управляемой среды одним из самых простых способов выполнения кода в блокировке загрузчика в c ++ является включение классов, встроенных в dll, для выполнения их инициализации в глобальной области видимости.

Единственное время, чтобы выполнить инициализацию объектов dll, - это сообщения DllMain от ОС, но во время этих сообщений активна блокировка загрузчика. блокировка загрузчика предотвращает одновременную загрузку различными библиотеками dll-файлов в DllMain одного dll одновременно.

Исправить проблему довольно сложно в C ++ (и, предположительно, в управляемых средах), поскольку, возможно, существует много неявных объектов, нуждающихся в построении в dll. Тем не менее, вам нужно найти код инициализации, который вызывается из DllMain, и убедиться, что он вызывается из явной инициализации / завершения работы функций dll, экспортируемых или выполняемых точно в срок.

...