一个线程之外HOWTO访问线程数据(Howto access thread data outside

2019-10-21 06:32发布

问:我启动MS文本到语音引擎中的一个线索,以避免对DLL_attach崩溃。 它开始罚款,以及文本到语音引擎被初始化,但我不能线程访问外部ISpVoice。 如何访问ISpVoice的线程之外? 这毕竟是一个全局变量...

您可以找到XPThreads: http://www.codeproject.com/KB/threads/XPThreads.aspx

#include <windows.h>
#include <sapi.h>
#include "XPThreads.h"


ISpVoice * pVoice = NULL;

unsigned long init_engine_thread(void* param)
{
Sleep(5000);
    printf("lolthread\n");



    //HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
    HRESULT hr = CoInitialize(NULL);

    if(FAILED(hr) )
    {
        MessageBox(NULL, TEXT("Failed To Initialize"), TEXT("Error"), 0);
        char buffer[2000] ;
        sprintf(buffer, "An error occured: 0x%08X.\n", hr);
        FILE * pFile = fopen ( "c:\\temp\\CoInitialize_dll.txt" , "w" );
        fwrite (buffer , 1 , strlen(buffer) , pFile );
        fclose (pFile);
    }
    else
    {   
        printf("trying to create instance.\n");
        //HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **) &pVoice);
        //hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **) &pVoice);
        //HRESULT hr = CoCreateInstance(__uuidof(ISpVoice), NULL, CLSCTX_INPROC_SERVER, IID_ISpVoice, (void **) &pVoice);
        HRESULT hr = CoCreateInstance(__uuidof(SpVoice), NULL, CLSCTX_ALL, IID_ISpVoice, (void **) &pVoice);
        if( SUCCEEDED( hr ) )
        {
            printf("Succeeded\n");
            hr = pVoice->Speak(L"The text to speech engine has been successfully initialized.", 0, NULL);
        }
        else
        {
            printf("failed\n");
            MessageBox(NULL, TEXT("Failed To Create COM instance"), TEXT("Error"), 0);
            char buffer[2000] ;
            sprintf(buffer, "An error occured: 0x%08X.\n", hr);
            FILE * pFile = fopen ( "c:\\temp\\CoCreateInstance_dll.txt" , "w" );
            fwrite (buffer , 1 , strlen(buffer) , pFile );
            fclose (pFile);
        }
    }






return NULL;
}


XPThreads* ptrThread = new XPThreads(init_engine_thread);


BOOL APIENTRY DllMain( HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
    //init_engine();
    LoadLibrary(TEXT("ole32.dll"));
    ptrThread->Run();
    break;
case DLL_THREAD_ATTACH:
    break;
case DLL_THREAD_DETACH:
    break;
case DLL_PROCESS_DETACH:
    if(pVoice != NULL)
    {
        pVoice->Release();
        pVoice = NULL;
    }
    CoUninitialize();
    break;
}
return TRUE;
}

Answer 1:

首先,你的问题是,你期待你开始时文件的静态initialisers正在运行已完成,而你的DllMain(线程)正在运行,但你正在做什么与它同步。 当然,如果你正在做一些与它同步,那么你会下降的,共有的,我张贴在回答您的链接详细说明的问题,犯规等问题 ...

其次,COM接口指针,通常,螺纹具体。 你不能,通常,通过获得一个在一个线程中CoCreateInstance()QueryInterface()然后只用它在另一个线程。 为了能够使用一个使用一个接口指针在你需要它名帅使用类似的东西线程另一个线程CoMarshalInterface()见这里 )。 但在此之前,你可以做,你需要确保你已经初始化COM的线程上,你不能做到这一点的,我在回答提出你的前一个问题的所有原因。

第三,你有什么理由要调用CoUninitialize()在你DllMain()为)你不知道什么线程你被要求和b)你不负责调用CoInitialize()上随机线程由应用程序拥有。

第四,调用LoadLibrary()是非常糟糕的原因,指出了这个链接 ,我贴在回答你的问题早。

所以,综上所述,正如我在回答你的其他问题说,你不能做你想在做什么DllMain() 它不这样做的地方。 正如我前面所说,你可以做的,当你让你运行一个线程DLL_PROCESS_ATTACH通知,但是当你这样做,这样你就不会死锁,并在那里加载您的COM对象遵守规则。 然后,您可以只从线程访问接口指针,你必须做你自己的编组从跨打电话到您的DLL到你的COM线程的线程传递值。 即使这样可能有更好的方式做你正在做什么(如全不管它是你正在建立它自己的COM对象暴露),但你没有给予足够的情况下,任何人拿出一个答案对你有真正的问题。

哦,最后...您使用的是基于你必须等待线程处理,你从回来的有缺陷的假设的XPThreads事情CreateThread()你不这样做,你可以只关闭它在创建后您的线索,你不感兴趣,等待它。 你可能想看看这个问题 ,看看为什么你可能不应该使用CreateThread()和应该,而是使用是_beginthreadex()



文章来源: Howto access thread data outside a thread