Неопределенная ссылка на CLSID_MMDeviceEnumerator и IID_IMMDeviceEnumerator

Попытка скомпилировать пример кода с помощью COM и CoCreateInstance() с помощью MinGW-w64 на C не увенчалась успехом.

#include <windows.h>
#include <mmdeviceapi.h>
#include <endpointvolume.h>

#include <stdlib.h>
#include <stdio.h>

extern const CLSID CLSID_MMDeviceEnumerator;
extern const IID IID_IMMDeviceEnumerator;

int main( void )
{
    CoInitialize( NULL );

    LPVOID device = NULL;
    const HRESULT ok = CoCreateInstance(    &CLSID_MMDeviceEnumerator, NULL, 
                                            CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, 
                                            &device );  
    CoUninitialize();

return EXIT_SUCCESS;
}

Компиляция с помощью: gcc main.c libole32.a -Wall -Wextra -o a

Хотя CLSID_MMDeviceEnumerator определен в mmdeviceapi.h, он не найден. На самом деле удаление моих определений extern из примера кода дает тот же результат, поскольку оба externs, похоже, определены в mmdeviceapi.h.

Когда я использовал __uuidof и компилировал с помощью g++, код работал, но эта «замена» C для __uuidof не работает.

Почему не найдены COM-идентификаторы?


person this    schedule 28.07.2015    source источник
comment
Попробуйте -luuid. Я не знаю, будут ли мультимедийные API, которые вы используете, поддерживаться чем-либо, кроме новейшего MinGW-w64 (и даже тогда я не знаю).   -  person andlabs    schedule 28.07.2015
comment
Вы определили их как extern, поэтому компилятор ожидает, что вы все равно их предоставите. Если вы не можете связать .lib (.a), определите статические переменные в проекте (с соответствующими значениями GUID).   -  person Roman R.    schedule 28.07.2015
comment
@РоманР. Да, я знаю об этом. Я не спрашиваю, как получить фактические значения идентификаторов.   -  person this    schedule 30.07.2015
comment
Думайте о __uuidof как о получении extern и автоматической статической переменной со значением. В вашем фрагменте кода вы выполняете только extern часть.   -  person Roman R.    schedule 30.07.2015


Ответы (1)


Решение при использовании MinGW-w64 состоит в том, чтобы включить заголовок #include <initguid.h> перед включением заголовков, содержащих идентификаторы COM, такие как mmdeviceapi.h, endpointvolue.h.

Тогда не нужны никакие дополнительные объявления, и идентификаторы можно использовать напрямую.

Решение:

#include <windows.h>
#include <initguid.h>
#include <mmdeviceapi.h>
#include <endpointvolume.h>

#include <stdlib.h>
#include <stdio.h>

int main( void )
{
    CoInitialize( NULL );

    LPVOID device = NULL;
    const HRESULT ok = CoCreateInstance(    &CLSID_MMDeviceEnumerator, NULL, 
                                            CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, 
                                            &device );  
    CoUninitialize();

return EXIT_SUCCESS;
}
person this    schedule 01.08.2015