Cannot call SAPI from dll

Posted by Quandary on Stack Overflow See other posts from Stack Overflow or by Quandary
Published on 2010-04-18T22:13:15Z Indexed on 2010/04/18 22:23 UTC
Read the original article Hit count: 599

Filed under:
|
|
|
|

Question: The below code works fine as long as it is in an executable. It uses the msft (text-to-)speech API (SAPI).

But as soon as I put it in a dll and load it with loadlibrary from an executable, it doesn't work.

I've also tried to change CoInitialize(NULL); to CoInitializeEx(NULL,COINIT_MULTITHREADED); and I tried with all possible flags ( COINIT_APARTMENTTHREADED, COINIT_MULTITHREADED, COINIT_DISABLE_OLE1DDE, COINIT_SPEED_OVER_MEMORY)

But it's always stuck at

hr = CoCreateInstance(__uuidof(SpVoice), NULL, CLSCTX_INPROC_SERVER, IID_ISpVoice, (void **) &pVoice);


I also tried those flags here: CLSCTX_INPROC_SERVER,CLSCTX_SERVER, CLSCTX_ALL, but nothing seems to help...

There are no errors, it doesn't crash, it just sleeps forever at CoCreateInstance...

This is the code as single exe (working)

#include <windows.h>
#include <sapi.h>
#include <iostream>
#include <cstdlib>


int main(int argc, char* argv[])
{   
    ISpVoice * pVoice = NULL;


//CoInitializeEx(NULL,COINIT_MULTITHREADED);
HRESULT hr = CoInitialize(NULL);
if( FAILED(hr) )
{
    MessageBox(NULL, TEXT("Failed To Initialize"), TEXT("Error"),0);
    printf("Failed!\n");

    char buffer[2000] ;
    sprintf(buffer, "An error occured: 0x%08X.\n", hr);
    FILE * pFile = fopen ( "c:\\temp\\CoInitialize_exe.txt" , "w" );
    fwrite (buffer , 1 , sizeof(buffer) , pFile );
    fclose (pFile);
}
else
{
    //CoGetClassObject(CLSID_SpVoice, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (void**) &pClsF);
    //hr = CoGetClassObject(CLSID_SpVoice, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (void**) &pClsF);
    hr = CoCreateInstance(__uuidof(SpVoice), NULL, CLSCTX_INPROC_SERVER, IID_ISpVoice, (void **) &pVoice);
    //HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **) &pVoice);
    if( SUCCEEDED( hr ) )
    {
        hr = pVoice->Speak(L"Test Test", 0, NULL);
        hr = pVoice->Speak(L"This sounds normal <pitch middle = '-10'/> but the pitch drops half way through", SPF_IS_XML, NULL );
        pVoice->Release();
        pVoice = NULL;
    }
    else
    {
        MessageBox(NULL, TEXT("Failed To Create a COM instance..."), TEXT("Error"),0);
        char buffer[2000] ;
        sprintf(buffer, "An error occured: 0x%08X.\n", hr);
        FILE     * pFile = fopen ( "c:\\temp\\CoCreateInstance_exe.txt" , "w" );
        fwrite (buffer , 1 , sizeof(buffer) , pFile );
        fclose (pFile);
    }
}

CoUninitialize();

return EXIT_SUCCESS;
}

This is the exe loading the dll (stays forever at printf("trying to create instance.\n"); )

#include <windows.h>
#include <sapi.h>
#include <iostream>
#include <cstdlib>

int main(int argc, char* argv[])
{
    // C:\Windows\System32\Speech\Common\sapi.dll
    //LoadLibraryA("sapi.dll");
    LoadLibraryA("Sapidll2.dll");
    return EXIT_SUCCESS; // Frankly, that would be nice...
}

And this is Sapidll2.dll

// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"

#include <iostream>
#include <cstdlib>
#include <string>

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



int init_engine()
{
ISpVoice * pVoice = NULL;

//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);
    }
}



if(pVoice != NULL)
{
    pVoice->Release();
    pVoice = NULL;
}
CoUninitialize();

return true ;
}






BOOL APIENTRY DllMain( HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
        case DLL_PROCESS_ATTACH:
            init_engine();
            break;
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
        break;
}
return TRUE;
}

© Stack Overflow or respective owner

Related posts about c++

Related posts about c