2

I'm using the P/Invoke in C# to call native function from C++ DLL as below:

  1. C++ DLL:

        extern "C"
        {
            // Function: Create Wmv video from sequences image. Codec: WMV3 (VC-1)
            __declspec(dllexport) bool __stdcall CreateWMV(...)
            {
            ...
            }
        }
    
  2. C# wrapper class. I create the C# wrapper class function to map with native C++ code:

        [DllImport("AVIEncoder.dll", EntryPoint = "CreateWMV", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool createWmv(...);
    

I'm sure that the parameters were marshaling correctly in C#, because it would run successfully when I called directly in client C# code. The issue only occurred when I put the function in background thread.

private void Test()
{
....
createWmv(...); // This call was processed without issue
Thread backgroundThread = new Thread(
    new ThreadStart(()=>
    {
        createWmv(...); // This call causes AccessViolationException
    }
}

The function createWmv() uses the Media Foundation Interface to generate Wmv video. I tried to debug and I found out that when I commented out the function IMFSinkWriter::WriteSample() in native code, the program run without causing the exception.

Thus, I wonder whether Microsoft has something weird in SinkWriter implementation. Does anyone have the same issue using Media Foundation this way?

mg30rg
  • 1,311
  • 13
  • 24
Khai Nguyen
  • 103
  • 1
  • 7
  • I think we should look at your C++ code for more details. (It seems like a complex threading issue which has something to do with i.e. Window handles aor thread heap.) – mg30rg Jun 01 '15 at 08:51
  • Try setting [ApartmentState to STA](http://stackoverflow.com/a/21488526/706456) – oleksii Jun 01 '15 at 08:54
  • @oleksii thanks, It seems to be run with STA ApartmentState now. – Khai Nguyen Jun 01 '15 at 09:33

1 Answers1

1

Follow oleksii's comment, I set below:

backgroundThread.TrySetApartmentState(ApartmentState.STA); // Add this to fix createWMV() in multithreading
backgroundThread.Name = "CreateVideoThead";
backgroundThread.Start();  

Now, the program could run without exception. Thanks for the concept of ApartmentState in C# threading.

Khai Nguyen
  • 103
  • 1
  • 7