COM ATL Threading Model or not
i am a little confused about COM threading models.
I got a C++ COM DLL. It is defined as single apartment model:
_ATL_APARTMENT_THREADED
My test app is written in C# and does the following:
start thread 1
thread 1:setName
start thread 2
thread 2:setName
since my dll is ATL I would expect the name attribute in the DLL to be whatever any thread is setting it to.
but it looks like COM is initializing a new object for every thread that is calling it.but I don't want that.
what am I doi开发者_JAVA百科ng wrong?
PS: C++ DLL StdAfx.h:
#define _ATL_APARTMENT_THREADED
C++ DLL MyApp.cpp:
myApp::InitInstance() {
CoInitialize(NULL);
}
C# TestApp Program.cs:
[STAThread]<br>
static void Main(string[] args) {
MyThreadClass t1 = new MyThreadClass(name1, pass1);
MyThreadClass t2 = new MyThreadClass(name2, pass2);
new Thread(new ThreadStart(t1.RunMethod)).Start();
Thread.Sleep(2000);
new Thread(new ThreadStart(t2.RunMethod)).Start();
C# TestApp MyThreadClass:
public void RunMethod() {
ComDllWrapper.SetName(name);
Console.WriteLine(ComDllWrapper.GetName());
Thread.Sleep(1000);
ComDllWrapper.SetPass(pass);
Console.WriteLine(ComDllWrapper.GetPass());
Thread.Sleep(1000);
...
}
C# TestApp ComDllWrapper:
[DllImport(DLLNAME)]
public static extern void SetName(string name);
...
these are only 2 values i set in the DLL (name and pass) but there are more. but the 2 threads don't write in the same object. every thread has its own object to write to.
this is how i initialize the dll:
C# TestApp ComDllWrapper
[DllImport("kernel32.dll", EntryPoint = "LoadLibrary", SetLastError = true)]
private static extern int LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpLibFileName);
public loadWrapper(string path) {
var filename = Path.Combine(path, DLLNAME);
LoadLibrary(filename);
Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
}
You don't ever instantiate a COM object in your code. You instantiate a COM object using new
on a type from an interop assembly (the one you get when you add a reference to a COM library) which calls CoCreateInstance()
WinAPI function under the hood. No call to CoCreateInstance()
- no threading models, so no restrictions on what threads can call what.
Please take time to read this very good explanation of COM apartments and threading.
Apartment threaded is like that - its the 'simple' model used by VB and C#. If you want to update a single object, you'll need to make your C++ dll use the Free threaded model instead, but then you are responsible for synchronisation between threads.
精彩评论