在多线程应用程序中使用 P/Invoke 和媒体基础接口时发生 AccessViolationException
AccessViolationException occured using P/Invoke with Media Foundation Interface in Multithread application
我在 C# 中使用 P/Invoke 从 C++ DLL 调用本机函数,如下所示:
C++ DLL:
extern "C"
{
// Function: Create Wmv video from sequences image. Codec: WMV3 (VC-1)
__declspec(dllexport) bool __stdcall CreateWMV(...)
{
...
}
}
C# 包装器 class。我创建了 C# 包装器 class 函数来映射原生 C++ 代码:
[DllImport("AVIEncoder.dll", EntryPoint = "CreateWMV", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool createWmv(...);
我确定参数在 C# 中正确编组,因为当我在客户端 C# 代码中直接调用时它会 运行 成功。
只有当我将函数放入后台线程时才会出现此问题。
private void Test()
{
....
createWmv(...); // This call was processed without issue
Thread backgroundThread = new Thread(
new ThreadStart(()=>
{
createWmv(...); // This call causes AccessViolationException
}
}
函数 createWmv() 使用媒体基础接口生成 Wmv 视频。我尝试调试,发现当我在本机代码中注释掉函数 IMFSinkWriter::WriteSample() 时,程序 运行 没有导致异常。
所以,不知道微软在SinkWriter的实现上是不是有什么奇怪的地方。
有没有人以这种方式使用 Media Foundation 遇到同样的问题?
关注oleksii的评论,我在下面设置:
backgroundThread.TrySetApartmentState(ApartmentState.STA); // Add this to fix createWMV() in multithreading
backgroundThread.Name = "CreateVideoThead";
backgroundThread.Start();
现在,程序可以 运行 无一例外。感谢 C# 线程中 ApartmentState 的概念。
我在 C# 中使用 P/Invoke 从 C++ DLL 调用本机函数,如下所示:
C++ DLL:
extern "C" { // Function: Create Wmv video from sequences image. Codec: WMV3 (VC-1) __declspec(dllexport) bool __stdcall CreateWMV(...) { ... } }
C# 包装器 class。我创建了 C# 包装器 class 函数来映射原生 C++ 代码:
[DllImport("AVIEncoder.dll", EntryPoint = "CreateWMV", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool createWmv(...);
我确定参数在 C# 中正确编组,因为当我在客户端 C# 代码中直接调用时它会 运行 成功。 只有当我将函数放入后台线程时才会出现此问题。
private void Test()
{
....
createWmv(...); // This call was processed without issue
Thread backgroundThread = new Thread(
new ThreadStart(()=>
{
createWmv(...); // This call causes AccessViolationException
}
}
函数 createWmv() 使用媒体基础接口生成 Wmv 视频。我尝试调试,发现当我在本机代码中注释掉函数 IMFSinkWriter::WriteSample() 时,程序 运行 没有导致异常。
所以,不知道微软在SinkWriter的实现上是不是有什么奇怪的地方。 有没有人以这种方式使用 Media Foundation 遇到同样的问题?
关注oleksii的评论,我在下面设置:
backgroundThread.TrySetApartmentState(ApartmentState.STA); // Add this to fix createWMV() in multithreading
backgroundThread.Name = "CreateVideoThead";
backgroundThread.Start();
现在,程序可以 运行 无一例外。感谢 C# 线程中 ApartmentState 的概念。