-1

I'm using rust for windows to use the win32 API.
However, I need to initialize com library to use some windows APIs, but I cannot find some classes ID (CLSID), to create an instance.
I need to find the Speech ISpVoice CLSID to use in my instance creation.
CLSID_SpVoice is the CLSID.
Also, I cannot find some macros like "FAILED", and "SUCCEEDED".
If anyone can direct me, that would be appreciated!
Also, if there's any error in my code, please highlight it me.
Code:

    use windows::Win32::System::Com::{CoInitializeEx, CoCreateInstance};
use windows::Win32::System::{Com, Ole};
use windows::core::{ HRESULT, Error };
use windows::Win32::Media::Speech::ISpVoice;

fn main() {
    let speaker: ISpVoice;
    unsafe {
        if CoInitializeEx(std::ptr::null(), Com::COINIT_MULTITHREADED) ==Result::Ok(()) {
            let hr: HRESULT = CoCreateInstance(, punkouter, dwclscontext)
        }
    }
}

If anything is unclear, please let me know!

IInspectable
  • 46,945
  • 8
  • 85
  • 181
  • https://www.magnumdb.com/search?q=CLSID_SpVoice => 96749377-3391-11d2-9ee3-00c04f797396. This site also tells you the value is available in the Windows SDK headers at %ProgramFiles(x86)%\Windows Kits\10\Include\10.0.22621.0\um\sapi53.h (adapt to your setup and SDK version). SUCCEEDED is defined here https://learn.microsoft.com/en-us/windows/win32/api/winerror/nf-winerror-succeeded and FAILED here https://learn.microsoft.com/en-us/windows/win32/api/winerror/nf-winerror-failed – Simon Mourier Jul 24 '22 at 12:07
  • @Simon Mourier, I haven't ask for C++ headers, I asked for the Windows crate (Rust For Windows). The two are different. – MEMOGAMER000 Jul 24 '22 at 12:30
  • I just assumed that `#define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0)` was easy to understand for any programmer. – Simon Mourier Jul 24 '22 at 21:10

2 Answers2

2

The windows crate declares the SpVoice constant which is the value of the CLSID_SpVoice class ID. As you have discovered, that's the CLSID you want to pass into CoCreateInstance.

The latter returns a windows::core::Result<T>, which models the same semantics as C code using the SUCCEEDED and FAILED macros would. You can either match on the Ok or Err variants manually, or use the ? operator for convenient error propagation:

use std::ptr;

use windows::{
    core::Result,
    Win32::{
        Media::Speech::{ISpVoice, SpVoice},
        System::Com::{CoCreateInstance, CoInitializeEx, CLSCTX_ALL, COINIT_APARTMENTTHREADED},
    },
};

fn main() -> Result<()> {
    unsafe { CoInitializeEx(ptr::null(), COINIT_APARTMENTTHREADED) }?;
    let _speaker: ISpVoice = unsafe { CoCreateInstance(&SpVoice, None, CLSCTX_ALL) }?;

    Ok(())
}

In case you need a CLSID that's not available through the windows crate, you can always construct a GUID constant using either from_values or from_u128:

const CLSID_SpVoice: GUID = GUID::from_u128(0x96749377_3391_11d2_9ee3_00c04f797396);

Note that the value is exactly the value you were given in a comment. Your assessment that C++ and Rust were any different with respect to COM is unfounded. They are indeed the same thing, just with different syntax.

IInspectable
  • 46,945
  • 8
  • 85
  • 181
-2

I found the solution.
I'll let my answer for anyone may encounter this problem:
Instead of providing the Class ID of the ISpVoice, I referenced the SpVoice struct to the CoCreateInstance method then it returns the SpVoice struct.
As following:

let speaker: ISpVoice = CoCreateInstance(&SpVoice, None, CLSCTX_ALL)?;

This method will work with any CoCreateInstance.
However, I'm still stuck with the two macros: "FAILED", and "SUCCEEDED".
If anyone know, please let me know also.