www.digitalmars.com         C & C++   DMDScript  

c++.stlsoft - COMSTL vs. MinGW: compiling error

reply Chinfu <chinfu.ku gmail.com> writes:
Hi,
    I encountered a problem while I tried to complile C++ source codes
(listed below). I use MinGW-5.1.4 [GCC 3.4.5 (mingw-vista special r3)]
for compiling under Windows XP Pro. (SP2) and STLSoft 1.9.57. The error
I got is as follows:

\MinGW\bin\g++.exe -c -I\MinGW\include -I\stlsoft-1.9.57\include -I"\Microsoft
Speech SDK 5.1\Include" test.cpp /stlsoft-1.9.57/include/comstl/util/creation_functions.hpp: In function `HRESULT stlsoft::comstl_project::co_create_instance(const CLSID&, I**, DWORD) [with I = ISpVoice]': /stlsoft-1.9.57/include/comstl/util/creation_functions.hpp:222: instantiated from `HRESULT stlsoft::comstl_project::co_create_instance(const CLSID&, stlsoft::ref_ptr<T, I, U>&, DWORD) [with T = ISpVoice, I = ISpVoice, U = ISpVoice]' test.cpp:19: instantiated from here d:/cygwin/home/chinfu/Sandbox/stlsoft-1.9.57/include/comstl/util/creatio _functions.hpp:128: error: incomplete type `stlsoft::comstl_project::IID_traits<ISpVoice>' used in nested name specifier I've tried googling but no luck. Could someone help me out? Thanks in advance. Chinfu C++ source codes: ----------------- #include <windows.h> #include <servprov.h> #include <sapi.h> #include <string> #include <iostream> #include <comstl/error/exceptions.hpp> #include <comstl/util/initialisers.hpp> #include <comstl/util/creation_functions.hpp> #include <stlsoft/smartptr/ref_ptr.hpp> #include <winstl/conversion/char_conversions.hpp> //COMSTL_IID_TRAITS_DEFINE(ISpVoice) class mySpeech { public: mySpeech() { static comstl::com_initializer coinit; HRESULT hr; if(FAILED(hr = comstl::co_create_instance(CLSID_SpVoice,_pVoice))) throw comstl::com_exception("Failed to create SpVoice COM instance",hr); } int sayit(const char* s, int n) { std::string(s,n); _pVoice->Speak(winstl::a2w(s), SPF_ASYNC, 0); return n; } void setRate(long n) { _pVoice->SetRate(n); } private: stlsoft::ref_ptr<ISpVoice> _pVoice; }; // main int main() { class mySpeech *msp; try { msp = new mySpeech(); } catch (comstl::com_exception &e){ std::cerr<< "error"; } string s("hello world"); msp.sayit(s); return 0; }
Oct 13 2008
parent reply Chinfu <chinfu.ku gmail.com> writes:
Hi,
   It's me again. I found my mistake. By adding "namespace stlsoft{ namespace
comstl{...} }" around the macro COMSTL_IID_TRAITS_DEFINE(ISpVoice), I've
compiled it without error.
(I also corrected some errors in souce codes in the previous post.)

But I got the following 'warning' while linking,
Warning: .drectve `/DEFAULTLIB:"uuid.lib" /DEFAULTLIB:"uuid.lib" ' unrecognized

And there is no output while I run the generated execution file. Any help is
appreciated. The source codes are listed below.

Chinfu

---
#include <windows.h>
#include <servprov.h>
#include <sapi.h>
#include <string>
#include <iostream>
#include <comstl/error/exceptions.hpp>
#include <comstl/util/initialisers.hpp>
#include <comstl/util/creation_functions.hpp>
#include <stlsoft/smartptr/ref_ptr.hpp>
#include <winstl/conversion/char_conversions.hpp>

namespace stlsoft {
namespace comstl_project {
    COMSTL_IID_TRAITS_DEFINE(ISpVoice)
}
}

class mySpeech {
    public:
        mySpeech() {
            static comstl::com_initializer coinit;
            HRESULT hr;
            if(FAILED(hr = comstl::co_create_instance(CLSID_SpVoice,_pVoice)))
                throw comstl::com_exception("Failed to create SpVoice COM
instance",hr);
        }
        int sayit(const char* s, int n) {
            std::string(s,n);
            _pVoice->Speak(winstl::a2w(s), SPF_ASYNC, 0);
            return n;
        }
        void setRate(long n) { _pVoice->SetRate(n); }
    private:
        //COM object smart pointer
        stlsoft::ref_ptr<ISpVoice> _pVoice;
};
// Main
int main() {
    class mySpeech *msp;
    try {
        msp = new mySpeech();
    } catch (comstl::com_exception &e){
        std::cerr<< "error";
    }
    const char* str="hello, world";
    msp->sayit(str,13);
    return 0;
}
Oct 14 2008
parent reply "Matthew Wilson" <matthew hat.stlsoft.dot.org> writes:
Am taking a look at this now.

btw, have you looked at VOLE: http://vole.sourceforge.net/. It simplifies the
use of COM Automation a whole lot

Matt

"Chinfu" <chinfu.ku gmail.com> wrote in message
news:gd1kht$1otn$1 digitalmars.com...
 Hi,
    It's me again. I found my mistake. By adding "namespace stlsoft{ namespace
comstl{...} }" around the macro
COMSTL_IID_TRAITS_DEFINE(ISpVoice), I've compiled it without error.
 (I also corrected some errors in souce codes in the previous post.)

 But I got the following 'warning' while linking,
 Warning: .drectve `/DEFAULTLIB:"uuid.lib" /DEFAULTLIB:"uuid.lib" ' unrecognized

 And there is no output while I run the generated execution file. Any help is
appreciated. The source codes are listed below.

 Chinfu

 ---
 #include <windows.h>
 #include <servprov.h>
 #include <sapi.h>
 #include <string>
 #include <iostream>
 #include <comstl/error/exceptions.hpp>
 #include <comstl/util/initialisers.hpp>
 #include <comstl/util/creation_functions.hpp>
 #include <stlsoft/smartptr/ref_ptr.hpp>
 #include <winstl/conversion/char_conversions.hpp>

 namespace stlsoft {
 namespace comstl_project {
     COMSTL_IID_TRAITS_DEFINE(ISpVoice)
 }
 }

 class mySpeech {
     public:
         mySpeech() {
             static comstl::com_initializer coinit;
             HRESULT hr;
             if(FAILED(hr = comstl::co_create_instance(CLSID_SpVoice,_pVoice)))
                 throw comstl::com_exception("Failed to create SpVoice COM
instance",hr);
         }
         int sayit(const char* s, int n) {
             std::string(s,n);
             _pVoice->Speak(winstl::a2w(s), SPF_ASYNC, 0);
             return n;
         }
         void setRate(long n) { _pVoice->SetRate(n); }
     private:
         //COM object smart pointer
         stlsoft::ref_ptr<ISpVoice> _pVoice;
 };
 // Main
 int main() {
     class mySpeech *msp;
     try {
         msp = new mySpeech();
     } catch (comstl::com_exception &e){
         std::cerr<< "error";
     }
     const char* str="hello, world";
     msp->sayit(str,13);
     return 0;
 }
Oct 15 2008
parent reply "Matthew Wilson" <matthew hat.stlsoft.dot.org> writes:
"Matthew Wilson" <matthew hat.stlsoft.dot.org> wrote in message
news:gd5jmp$1p2f$1 digitalmars.com...
 Am taking a look at this now.

 btw, have you looked at VOLE: http://vole.sourceforge.net/. It simplifies the
use of COM Automation a whole lot
Scratch that. SAPI does not support automation (IDispatch). Sorry for the misdirect
Oct 15 2008
parent reply "Matthew Wilson" <matthew hat.stlsoft.dot.org> writes:
"Matthew Wilson" <matthew hat.stlsoft.dot.org> wrote in message
news:gd5l7s$1rlt$1 digitalmars.com...
 "Matthew Wilson" <matthew hat.stlsoft.dot.org> wrote in message
news:gd5jmp$1p2f$1 digitalmars.com...
 Am taking a look at this now.

 btw, have you looked at VOLE: http://vole.sourceforge.net/. It simplifies the
use of COM Automation a whole lot
Scratch that. SAPI does not support automation (IDispatch). Sorry for the misdirect
Doh! Wrong again. It does. I'm writing a couple of examples of how to do all this ... be with you shortly. Matt
Oct 15 2008
parent reply "Matthew Wilson" <matthew hat.stlsoft.dot.org> writes:
 btw, have you looked at VOLE: http://vole.sourceforge.net/. It simplifies the
use of COM Automation a whole lot
I'm writing a couple of examples of how to do all this ... be with you shortly.
I've written up an example using ISpVoice directly, and it fails to talk for me also. I will try and find out why. In the meantime, here's an example using VOLE. #include <vole/vole.hpp> #include <comstl/util/initialisers.hpp> #include <iostream> int main(int /* argc */, char** /* argv */) { try { comstl::com_initialiser coinit; vole::object speaker = vole::object::create("SAPI.SpVoice"); #if defined(STLSOFT_COMPILER_IS_MSVC) && \ _MSC_VER < 1310 // VC++ 6 cannot use the "normal" VOLE way of explicitly // specialising the method function template on return type, so // we have to use invoke_method_v() speaker.invoke_method_v(L"Speak", "I have something to say!", 0); #else /* ? _DEBUG */ // The "normal" VOLE way speaker.invoke_method<void>(L"Speak", "I have something to say!", 0); #endif /* _DEBUG */ return EXIT_SUCCESS; } catch(std::bad_alloc&) { std::cerr << "out of memory" << std::endl; } catch(vole::vole_exception& x) { std::cerr << "operation failed: " << x.what() << ": " << winstl::error_desc_a(x.hr()) << std::endl; } catch(std::exception& x) { std::cerr << "operation failed: " << x.what() << std::endl; } catch(...) { std::cerr << "unexpected condition" << std::endl; } return EXIT_FAILURE; } I'm also doing a FastFormat version. I'll put them all up on the STLSoft wiki site shortly. HTH Matt
Oct 15 2008
next sibling parent "Matthew Wilson" <matthew hat.stlsoft.dot.org> writes:
Here's the FastFormat example (with error-handling elided)



#include <fastformat/fastformat.hpp>
#include <fastformat/sinks/speech.hpp>

int main(int argc, char** argv)
{
    {   // Say one thing only

        fastformat::write(fastformat::speech_sink(), "I have something to
say!");

    }

    {   // Say several things

        fastformat::speech_sink speaker;

        fastformat::write(speaker, "I have something to say!");

        fastformat::write(speaker, "I have something else to say!");
    }

    return EXIT_SUCCESS;
}
Oct 15 2008
prev sibling parent "Matthew Wilson" <matthew hat.stlsoft.dot.org> writes:
If you look again at the code

class mySpeech {
    public:
        mySpeech() {
            static comstl::com_initializer coinit;
            HRESULT hr;
            if(FAILED(hr = comstl::co_create_instance(CLSID_SpVoice,_pVoice)))
                throw comstl::com_exception("Failed to create SpVoice COM
instance",hr);
        }
        int sayit(const char* s, int n) {
            std::string(s,n);
            _pVoice->Speak(winstl::a2w(s), SPF_ASYNC, 0);
            return n;
        }
        void setRate(long n) { _pVoice->SetRate(n); }
    private:
        //COM object smart pointer
        stlsoft::ref_ptr<ISpVoice> _pVoice;
};
// Main
int main() {
    class mySpeech *msp;
    try {
        msp = new mySpeech();
    } catch (comstl::com_exception &e){
        std::cerr<< "error";
    }
    const char* str="hello, world";
    msp->sayit(str,13);
    return 0;
}


This fails to speak because:
- the call to sayit() is made immediately before the program exits.
- the Speak() command is passed the SPF_ASYNC flag, which causes the speech to
be executed on a worker thread

So the reason if fails to speak is because the program exits before it can get
it out.

There are two ways to make this speak:
- add a Sleep() call after sayit() - 1.5 seconds is required on my system to
get out the whole sentence
- change SFP_ASYNC to SPF_DEFAULT, causing the Speak() call to be synchronous

HTH

Matt
Oct 15 2008