1

I am trying to write an application that takes in sound from the default audio recording device on a computer. When running any code that accesses DirectX from my managed code i get this error:

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();

and

Device d = new Device(DSoundHelper.DefaultCaptureDevice);

and

Capture c = new Capture(DSoundHelper.DefaultCaptureDevice);

all cause the LoaderLock MDA to pop up and tell me there is a problem. I have scoured the internet (stackoverflow included) for solutions to this problem, but most people just say to turn off the warning, which does not work. When I turn off the warning, a generic ApplicationException is thrown, which is even less useful. I have seen the answers to this question as well, which didn't help because he said to remove the code that is causing the error. Others have said "fix your code."

My questions are:

how can I call any (preferably managed) DirectX code from C# without getting this error?

edit: this is the stack trace I get:

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()
4

1 回答 1

2

在托管环境之外,C++ 中在加载程序锁中执行代码的最简单方法之一是让嵌入在 dll 中的类在全局范围内执行它们的初始化。

唯一一次对 dll 对象进行初始化是在来自操作系统的 DllMain 消息期间 - 但在这些消息期间,加载程序锁定处于活动状态。加载器锁可防止加载 dll 的不同线程同时进入单个 dll 的 DllMain。

在 C++(可能是托管环境)中解决这个问题非常困难,因为可能有许多隐式对象需要在 dll 中构造。尽管如此,您需要找到从 DllMain 调用的初始化代码,并确保它是从 dll 导出的显式初始化/关闭函数调用的,或者是即时完成的。

于 2010-04-02T16:19:18.250 回答