c++.stlsoft - COMSTL vs. MinGW: compiling error
- Chinfu <chinfu.ku gmail.com> Oct 13 2008
- Chinfu <chinfu.ku gmail.com> Oct 14 2008
- "Matthew Wilson" <matthew hat.stlsoft.dot.org> Oct 15 2008
- "Matthew Wilson" <matthew hat.stlsoft.dot.org> Oct 15 2008
- "Matthew Wilson" <matthew hat.stlsoft.dot.org> Oct 15 2008
- "Matthew Wilson" <matthew hat.stlsoft.dot.org> Oct 15 2008
- "Matthew Wilson" <matthew hat.stlsoft.dot.org> Oct 15 2008
- "Matthew Wilson" <matthew hat.stlsoft.dot.org> Oct 15 2008
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
/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
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
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
(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
"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
"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
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
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
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









"Matthew Wilson" <matthew hat.stlsoft.dot.org> 