Во-первых, ваша проблема в том, что вы ожидаете, что поток, который вы запускаете при запуске статических инициализаторов файла, завершится во время работы DllMain (), и все же вы ничего не делаете для синхронизации с ним. Конечно, если вы делаете что-то для синхронизации с этим, то вы бы не справились с проблемами, которые были подробно описаны в ссылке, которую я разместил в ответ на ваш другой вопрос ...
Во-вторых, указатели интерфейса COM, как правило, зависят от потока. Обычно вы не можете получить один в одном потоке через CoCreateInstance()
или QueryInterface()
, а затем просто использовать его в другом потоке. Чтобы иметь возможность использовать указатель интерфейса в другом потоке, вам нужно перенаправить его в этот поток, используя что-то вроде CoMarshalInterface()
(см. здесь ). Но прежде чем вы сможете это сделать, вам нужно убедиться, что вы инициализировали COM в потоке, и вы не можете сделать это по всем причинам, которые я привел в ответ на ваш предыдущий вопрос.
В-третьих, у вас нет оснований для вызова CoUninitialize()
в вашем DllMain()
как a) вы не знаете, к какому потоку вы вызываетесь, и b) вы не несете ответственности за вызов CoInitialize()
для этого случайный поток, которым владеет приложение.
В-четвертых, звонок на LoadLibrary()
ОЧЕНЬ ПЛОХО по причинам, указанным в этой ссылке , которую я разместил в ответ на ваш предыдущий вопрос.
Итак, в заключение, как я сказал в ответ на ваш другой вопрос, вы не можете делать то, что вы хотите сделать в DllMain()
. Это не место, чтобы сделать это. Как я уже говорил ранее, вы МОЖЕТЕ выполнить поток, когда получите уведомление DLL_PROCESS_ATTACH
, но при этом соблюдаете правила, чтобы не блокировать и не загружать COM-объект там. После этого вы можете ТОЛЬКО получить доступ к указателю на интерфейс из этого потока, и вам придется выполнить собственный маршаллинг для передачи значений из потоков, которые вызывают в вашу DLL, в ваш поток COM. Даже тогда, возможно, есть лучший способ сделать то, что вы делаете (например, выставить все, что вы создаете, так как это СОБСТВЕННЫЙ COM-объект), но вы не даете достаточно контекста, чтобы кто-нибудь смог найти ответ к реальной проблеме, которая у вас есть.
Да, и наконец ... Используемая вами вещь XPThreads основана на ошибочном допущении, что вам НЕОБХОДИМО дождаться дескриптора потока, который вы получите от CreateThread()
, нет, вы можете просто закрыть его после того, как вы создали свою тему, так как вы не заинтересованы в ее ожидании. Возможно, вы захотите взглянуть на этот вопрос , чтобы понять, почему вам, вероятно, не следует использовать CreateThread()
, а вместо этого следует использовать _beginthreadex()
.