Ваш код не является допустимым COM, потому что вы передаете указатель непосредственно от одной STA к другой, что COM не позволяет.
В COM указатели интерфейса имеют «сходство с квартирой», их можно использовать только внутри квартиры. Чтобы передать указатель из одной STA в другую или между STA и MTA, необходимо «маршалировать» указатель на безопасное представление, которое затем не сортируется принимающим потоком.
Самый простой способ сделать это - использовать Global Interface Table ; вы регистрируете интерфейс с ним в одном потоке и возвращаете DWORD, который затем используете в другом потоке, чтобы получить версию интерфейса, которую может использовать другой поток.
Если оба потока MTA, вы можете избежать этого. В то время как STA один на поток - каждый поток STA имеет свою собственную структуру - MTA совместно используется всеми потоками MTA. Это означает, что потоки MTA могут свободно передавать COM-указатели между собой. (Но они все равно должны маршалировать при передаче указателей на потоки STA или из них.)
Вообще говоря, вы не меняете код между STA или MTA, вы обычно решаете это один раз в самом начале. Если у потока есть пользовательский интерфейс, то он нуждается в цикле сообщений и обычно является STA. Если пользовательского интерфейса нет, вы можете решить использовать MTA. Но как только вы примете это решение и напишете свой код, редко можно будет перейти к другому позже, так как выбор одного или другого имеет другие требования и предположения, которые влияют на код; перейдите с STA на MTA или наоборот, и вам придется внимательно просмотреть код и посмотреть, нужно ли менять такие вещи, как назначение указателей.