2010-04-02 2 views
1

Я пытаюсь написать приложение, которое воспроизводит звук с устройства записи звука по умолчанию на компьютере. При запуске любого кода, обращающегося DirectX из моего управляемого кода я получаю эту ошибку:LoaderLock был обнаружен, и выключение предупреждения не помогает

DLL 'C:\Windows\assembly\GAC\Microsoft.DirectX.DirectSound\1.0.2902.0__31bf3856ad364e35\Microsoft.DirectX.DirectSound.dll' is attempting managed execution inside OS Loader lock. Do not attempt to run managed code inside a DllMain or image initialization function since doing so can cause the application to hang.

DevicesCollection coll = new DevicesCollection(); 

и

Device d = new Device(DSoundHelper.DefaultCaptureDevice); 

и

Capture c = new Capture(DSoundHelper.DefaultCaptureDevice); 

все привести к тому LoaderLock MDA всплывал и скажите, что есть проблема. Я просмотрел интернет (stackoverflow included) для решения этой проблемы, но большинство людей просто говорят, чтобы отключить предупреждение, которое не работает. Когда я выключаю предупреждение, генерируется общее исключение ApplicationException, что еще менее полезно. Я также видел ответы на this question, что не помогло, потому что он сказал, чтобы удалить код, вызывающий ошибку. Другие сказали: «Исправьте свой код».

Мои вопросы:

как я могу назвать любую (желательно управляемый) 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() 
+0

Какое исключение выбрасывается? – SLaks

+0

Исключение хорошее, опубликуйте StackTrace. –

+1

его буквально называемое ApplicationException с сообщением «Ошибка в приложении» –

ответ

2

Вне управляемой среды, один из самых простых способов в C++ для выполнения кода в блокировки загрузчика, чтобы иметь классы встроенные в DLL файлы выполнять их инициализация в глобальном масштабе.

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

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