Я немного запутался в моделях COM-потоков.
Я получил C ++ COM DLL. Он определяется как модель одной квартиры:
_ATL_APARTMENT_THREADED
Мое тестовое приложение написано на C # и выполняет следующие действия:
start thread 1
thread 1:setName
start thread 2
thread 2:setName
, поскольку моя dll - ATL, я ожидал бы, что атрибут имени в DLL будет таким, каким его устанавливает любой поток.
но похоже, что 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 значения, которые я установил в 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());
}