我对COM线程模型有点困惑。COM ATL线程模型与否
我得到了一个C++ COM DLL。它被定义为单身公寓模式:
_ATL_APARTMENT_THREADED
我的测试应用程序是用C#编写并执行以下操作:
start thread 1
thread 1:setName
start thread 2
thread 2:setName
,因为我的DLL是ATL我希望在DLL name属性无论任何线程设置它。
但它看起来像COM正在为每个正在调用它的线程初始化一个新对象。
但我不想那样。
我做错了什么?
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);
...
这些仅是2值I在设定DLL(名称和传递),但也有更多。但2个线程不写入同一个对象。每个线程都有自己的对象来写入。
这是我如何初始化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());
}
显示一些真实的代码。 – Henrik 2011-03-18 10:32:04
+1 @Henrik:Juergen,展示了如何初始化COM对象以及如何在线程之间共享它。通常你必须确保你的对象被正确编组。 – Andrey 2011-03-18 12:57:25
你似乎没有实例化一个COM对象 - 你只需要使用DllImport。这是没有实际的COM - 你只是在一个调用它的线程上执行一个函数。 – sharptooth 2011-03-18 13:05:27