2013-11-27 52 views
1

很多錯誤所以我第一次嘗試做一個簡短的例子,只是爲了在主函數中工作文本到語音。這工作,沒有問題。代碼如下所示:Qt中的Windows Speech API。在main()中工作,但在類

main.cpp中:

#include <QtGui/QGuiApplication> 
#include "qtquick2applicationviewer.h" 
#include <QDebug> 
#include <sapi.h> 
#include <windows.h> 
#include <atlbase.h> 
#include "sphelper.h" 

int main(int argc, char *argv[]) 
{ 
    QGuiApplication app(argc, argv); 

    QtQuick2ApplicationViewer viewer; 
    viewer.setMainQmlFile(QStringLiteral("qml/GC/main.qml")); 
    viewer.showExpanded(); 

    CComPtr<ISpObjectToken>   cpVoiceToken; 
    CComPtr<IEnumSpObjectTokens> cpEnum; 
    ISpVoice *      pVoice = NULL; 
    ULONG       count = 0; 

    if (FAILED(::CoInitialize(NULL))) 
     return FALSE; 

    HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice); 

    if(SUCCEEDED(hr)) 
    { 
     //Enumerate voices. 
     hr = SpEnumTokens(SPCAT_VOICES, NULL, NULL, &cpEnum); 
    } 
    else 
    { 
     qDebug() << "Failed to initialize SAPI5"; 
    } 

    if(SUCCEEDED(hr)) 
    { 
     //Get number of voices. 
     hr = cpEnum->GetCount(&count); 
     qDebug() << "TTS voices found: " + QString::number(count); 
    } 
    else 
    { 
     qDebug() << "Failed to enumerate voices. Using default."; 
     hr = S_OK; 
    } 

    if(SUCCEEDED(hr)) 
    { 
     cpVoiceToken.Release(); 

     cpEnum->Item(4, &cpVoiceToken); 

     pVoice->SetVoice(cpVoiceToken); 
     hr = pVoice->Speak(L"Hello! How are you?", 0, NULL); 
     pVoice->Release(); 
     pVoice = NULL; 
    } 

    ::CoUninitialize(); 



    qDebug() << "End"; 

    return app.exec(); 
} 

此輸出我已經安裝在計算機上的聲音的數量和文本說:「!?你好,你」。

當我現在這個代碼移到類:

tts.h:

#ifndef TTS_H 
#define TTS_H 

#include <sapi.h> 
#include <windows.h> 
#include <atlbase.h> 
#include "sphelper.h" 

class Tts 
{ 
public: 
    Tts(); 
    bool Initialize(); 
    HRESULT Speak(char * text, ISpVoice * pVoice); 

private: 

}; 

#endif // TTS_H 

tts.cpp:

#include "tts.h" 
#include <QDebug> 
#include <sapi.h> 
#include <windows.h> 
#include <atlbase.h> 
#include "sphelper.h" 


Tts::Tts() 
{ 
} 

bool Tts::Initialize() 
{  
    CComPtr<ISpObjectToken>   cpVoiceToken; 
    CComPtr<IEnumSpObjectTokens> cpEnum; 
    ISpVoice *      pVoice = NULL; 
    ULONG       count = 0; 

    if (FAILED(::CoInitialize(NULL))) 
     return false; 

    HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice); 

    if(SUCCEEDED(hr)) 
    { 
     //Enumerate voices. 
     hr = SpEnumTokens(SPCAT_VOICES, NULL, NULL, &cpEnum); 
    } 
    else 
    { 
     qDebug() << "Failed to initialize SAPI5"; 
    } 

    if(SUCCEEDED(hr)) 
    { 
     //Get number of voices. 
     hr = cpEnum->GetCount(&count); 
     qDebug() << "TTS voices found: " + QString::number(count); 
    } 
    else 
    { 
     qDebug() << "Failed to enumerate voices. Using default."; 
     hr = S_OK; 
    } 

    if(SUCCEEDED(hr)) 
    { 
     cpVoiceToken.Release(); 

     cpEnum->Item(4, &cpVoiceToken); 

     pVoice->SetVoice(cpVoiceToken); 
     Speak("Some text here", pVoice); 
     pVoice->Release(); 
     pVoice = NULL; 
    } 

    ::CoUninitialize(); 

    return true; 
} 

HRESULT Tts::Speak(char * text, ISpVoice * pVoice) 
{ 
    HRESULT hr; 

    hr = pVoice->Speak(L"Hello! How are you?", 0, NULL); 

    return hr; 
} 

main.cpp中:

#include <QtCore> 
#include <QtGui/QGuiApplication> 
#include <QtQuick> 
#include "qtquick2applicationviewer.h" 
#include <QDebug> 
#include "tts.h" 

int main(int argc, char *argv[]) 
{ 
    QGuiApplication app(argc, argv); 
    QtQuick2ApplicationViewer viewer; 
    viewer.setMainQmlFile(QStringLiteral("qml/GC/main.qml")); 

    viewer.showExpanded(); 
    viewer.showMaximized(); 

    return app.exec(); 
} 

我剛纔加入了tts.h頭文件,並得到很多錯誤。我試過重建,清理和刪除生成文件夾中的文件,但沒有運氣。當沒有包含在主程序中的tts.h頭文件時,程序正常運行。

我不明白爲什麼會發生這種情況,當我將它移動到類文件。這裏是.pro文件和錯誤:

的.pro:

# Add more folders to ship with the application, here 
folder_01.source = qml/GC 
folder_01.target = qml 
DEPLOYMENTFOLDERS = folder_01 

# Additional import path used to resolve QML modules in Creator's code model 
QML_IMPORT_PATH = 

# If your application uses the Qt Mobility libraries, uncomment the following 
# lines and add the respective components to the MOBILITY variable. 
# CONFIG += mobility 
# MOBILITY += 

# The .cpp file which was generated for your project. Feel free to hack it. 
SOURCES += main.cpp \ 
    simkeyevent.cpp \ 
    serialthread.cpp \ 
    serial.cpp \ 
    tts.cpp 

# Installation path 
# target.path = 

# Please do not modify the following two lines. Required for deployment. 
include(qtquick2applicationviewer/qtquick2applicationviewer.pri) 
qtcAddDeployment() 

#Manually added: 
QT += core gui serialport 

HEADERS += \ 
    simkeyevent.h \ 
    serialthread.h \ 
    serial.h \ 
    tts.h 

錯誤:

First errors

+0

sapi.h是否包含警衛?重定義錯誤表明它沒有,並且您多次包含sapi.h。嘗試從.cpp(或標題,如果不需要的話)中刪除包含的內容,那麼它們只會包含在您的代碼中一次。 –

+0

是sapi.h。無論如何,我儘可能地嘗試過,但仍然如此。 – Phat

回答

1

我會重構你的tts.h以前瞻聲明ISpVoice接口,並刪除所有的依賴;這也會大大減少編譯時間。

#ifndef TTS_H 
#define TTS_H 

interface ISpVoice; // or struct ISpVoice, if GCC hates interface decls. 

class Tts 
{ 
public: 
    Tts(); 
    bool Initialize(); 
    HRESULT Speak(char * text, ISpVoice * pVoice); 

private: 

}; 

#endif // TTS_H 

或者,您的#包括訂單有點奇怪;你#包括sapi.h之前windows.h,並且這兩者之間有一些依賴關係。嘗試顛倒它們。

你離開出錯上市的行號,但它看起來像最初的錯誤是在這條線在sapi.h:

typedef interface ISpNotifySource ISpNotifySource; 

所以我懷疑是GCC是有一些問題的interface關鍵字,而其他一些頭文件則掩蓋了這一點。

+0

我照你所說做了,並使用「struct ISpVoice」(它沒有接口關鍵字)並刪除了依賴關係。這工作。我真的很想知道爲什麼和造成這個問題的原因。你能說幾句話嗎? – Phat

+1

已更新答案... –

相關問題