-1

mixerXXXWin32 のAPI 関数をラップする小さな OOP/RAII ライブラリを開発しています。

私はMIXERLINE構造をカプセル化するクラスを書いているので、私のMixerLineクラスはこれをヘッダーとして持っています:

#pragma once
#define UNICODE
#include <stdio.h>
#include <string>
#include <windows.h>
#include "MixerDevice.h"

//////////////////////////////

class MixerLine {

private:
    MIXERLINE _mixerLine;

public:

    MixerLine(MixerDevice& parentMixer, DWORD destinationIndex); 

    ~MixerLine();

};

ただし、構文エラーが発生します(VC9で):

エラー 2 エラー C2061: 構文エラー: 識別子 'MixerDevice' d:\tfs\misc\winwavein\mixerline.h

メッセージが役に立たないのはなぜですか? 何が悪いのかわかりません。

FWIW、ファイルにはまったくエラーはありませんMixerDevice.h

編集:元のファイル全体は次のとおりです。

MixerLine.h

#pragma once

#define UNICODE
#include <stdio.h>
#include <string>

#include <windows.h>

#include "MixerDevice.h"

//////////////////////////////

class MixerLine {

private:
    MIXERLINE _mixerLine;

public:

    MixerLine(MixerDevice& parentMixer, DWORD destinationIndex); 

    ~MixerLine();

    // Properties

    DWORD getDestinationLineIndex() {
        return _mixerLine.dwDestination;
    }   

    DWORD getSourceIndex() {
        return _mixerLine.dwSource;
    }

    DWORD getLineId() {
        return _mixerLine.dwLineID;
    }

    DWORD getStatus() {
        return _mixerLine.fdwLine;
    }

    std:wstring getStatusString() {

        switch( _mixerLine.fdwLine ) {
            case MIXERLINE_LINEF_ACTIVE:
                return L"MIXERLINE_LINEF_ACTIVE";
            case MIXERLINE_LINEF_DISCONNECTED:
                return L"MIXERLINE_LINEF_DISCONNECTED";
            case MIXERLINE_LINEF_SOURCE:
                return L"MIXERLINE_LINEF_SOURCE";
            default:
                return L"";
        }

    }

    DWORD getUserData() {
        return _mixerLine.dwUser;
    }

    DWORD getComponentType() {
        return _mixerLine.dwComponentType;
    }
};

MixerDevice.h

#pragma once
#define UNICODE

#include <memory>
#include <stdio.h>
#include <iostream>
#include <vector>

#include <windows.h>

////////////////////////

#include "MixerLine.h"

class MixerDevice {

    private:
        DWORD     _deviceId;
        HMIXER    _mixerHandle;
        MIXERCAPS _mixerCaps;

    public:
        MixerDevice(DWORD deviceId);
        ~MixerDevice();

        void enumerateLines();

        // Properties

        DWORD getDeviceId() {
            return _deviceId;
        }

        HMIXEROBJ getHandle() {
            return (HMIXEROBJ)_mixerHandle;
        }

        // Caps

        WORD getManufacturerId() {
            return _mixerCaps.wMid;
        }
        WORD getProductId() {
            return _mixerCaps.wPid;
        }
        MMVERSION getDriverVersion() {
            return _mixerCaps.vDriverVersion;
        }
        WCHAR* getProductName() {
            return _mixerCaps.szPname;
        }
        DWORD getSupportBits() {
            return _mixerCaps.fdwSupport;
        }
        DWORD getDestinationCount() {
            return _mixerCaps.cDestinations;
        }
    };

MixerDevice.cpp (コンパイルしようとしているファイル):

#include "MixerDevice.h"

using namespace std;

MixerDevice::MixerDevice(DWORD deviceId) {

    _deviceId = deviceId;

    MMRESULT result;

    result = mixerOpen( &_mixerHandle, deviceId, NULL, NULL, MIXER_OBJECTF_MIXER );
    if( result != MMSYSERR_NOERROR ) throw new exception("Call to mixerOpen failed.", result);

    result = mixerGetDevCaps( (UINT)_mixerHandle, &_mixerCaps, sizeof(MIXERCAPS) );
    if( result != MMSYSERR_NOERROR ) throw new exception("Call to mixerGetDevCaps failed.", result);
}

MixerDevice::~MixerDevice() {

    MMRESULT result = mixerClose( _mixerHandle );
    if( result != MMSYSERR_NOERROR ) exit(666);
}

// Methods

void MixerDevice::enumerateLines() {    
}
4

2 に答える 2

2

Luchian Grigoreがすでに述べたように、ヘッダー全体(少なくとも、こことIMHO)を含めるよりも、前方宣言で十分な場合は、前方宣言の方が適しています。

#pragma once円形の包含には役立ちません。無限の包含を回避するだけです。_

しかし、包含は以下の範囲内で始まりますMixerDevice.cpp

MixerDevice.cpp --- #include> MixerDevice.h --- > #includeMixerLine.h #include---> MixerDevice.h

その最後の#includeディレクティブは、#pragma onceinのために何もしませんMixerDevice.h。プリプロセッサは、次のような単一のドキュメント(翻訳ユニット)をアセンブルします(使用/Pまたは/showIncludes表示)。

  1. いくつかのStdLibおよびWindowsヘッダーの内容
  2. MixerLine.hの内容
  3. MixerDevice.hの内容
  4. MixerDevice.cppの内容

これは、コンパイラが効果的に入力として受け取るものです。さて、コンパイラが:の内容内の行に到達するとMixerLine.h

MixerLine(MixerDevice& parentMixer, DWORD destinationIndex);

名前MixerDeviceはまだわかっていません。その名前は、のコンテンツ内のドキュメントの「下」に導入されていますMixerDevice.hMixerDevice名前を使用する前に、少なくともクラスを宣言する必要があります。MixerDevice現在はに依存していないため、包含順序を変更することもできますが、この方法で後でさらに問題が発生する可能性MixerLineがあります。

Luchian Grigoreとの話し合いの後、私は次のことを指摘したいと思います。

包含順序を逆にして問題を解決しないでください。この解決策は、この特定の場合にMixerDevice.hのみ機能し、で宣言されている名前がない場合にのみ機能しMixerLine.hます。Luchian Grigoreが述べたように、代わりに前方宣言を使用してください。

于 2012-06-23T14:08:50.750 に答える
2

コードに循環インクルードがありますが、機能しないのも不思議ではありません。ヘッダーで可能な場合は、インクルードを前方宣言に置き換える必要があります。

MixerLine.h - インクルードを前方宣言に置き換えます。

//#include "MixerDevice.h"
class MixerDevice;

実装を実装ファイルに移動します。

于 2012-06-23T13:19:45.493 に答える