0

未定義の参照に関する StackOverflow に関する多くの質問を読みましたが、含まれているヘッダーで定義されている定数への未定義の参照に関するものは特にないようです。どこかで有効な答えを逃した場合はお詫び申し上げます。

Qt (5.5) 内で C++ をコンパイルするために MinGW 32 ビット (4.9.2) を間接的に使用しています。

含まれているファイルの 1 つで定数が定義されています#defineが、プロジェクトがビルドされると、コンパイラは .cpp 内の未定義の参照について不平を言います。

奇妙なことに、定数がその使用の上の行に存在するかどうかをテストしようとしましたが、これは問題ありません。

コンパイラの出力は次のとおりです。

g++ -Wl,-subsystem,windows -mthreads -o debug\THEPROJECT.exe object_script.THEPROJECT.Debug  -lmingw32 -LC:/Qt/5.5/mingw492_32/lib -lqtmaind -lshell32 -lole32 -lQt5Quickd -lQt5Guid -lQt5Qmld -lQt5Networkd -lQt5Cored 
./debug\RtAudio.o: In function `ZN11RtApiWasapi13getDeviceInfoEj':
C:\Users\ME\Documents\Code\build-THEPROJECT-Desktop_Qt_5_5_1_MinGW_32bit-Debug/../THEPROJECT/thirdparty/RtAudio.cpp:4128: undefined reference to `KSDATAFORMAT_SUBTYPE_IEEE_FLOAT'

.cpp の前半には、

#include <audioclient.h>

それは順番に持っています

#include <mmreg.h>
#include <ks.h>
#include <ksmedia.h>

mmreg.h 内で定数が定義されています

#define DEFINE_GUIDEX(name) EXTERN_C const CDECL GUID name
#define DEFINE_GUIDSTRUCT(g,n) DEFINE_GUIDEX(n)
#define DEFINE_GUIDNAMED(n) n
...
#define STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_IEEE_FLOAT)
DEFINE_GUIDSTRUCT("00000003-0000-0010-8000-00aa00389b71", KSDATAFORMAT_SUBTYPE_IEEE_FLOAT);
#define KSDATAFORMAT_SUBTYPE_IEEE_FLOAT #define DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)

ksmedia.h 内でも定義されていることに注意してください。#error ディレクティブを配置 (および後で削除) することで、この定義が実行されることがわかりますが、奇妙なことに「再定義」警告はスローされません。#ifndefつまり、それをバイパスしているようには見えません。

#define KSDATAFORMAT_SUBTYPE_IEEE_FLOAT DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)

.cpp ファイル内で定数が使用されます

  if ( deviceFormat->wFormatTag == WAVE_FORMAT_IEEE_FLOAT ||
       ( deviceFormat->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
         ( ( WAVEFORMATEXTENSIBLE* ) deviceFormat )->SubFormat == KSDATAFORMAT_SUBTYPE_IEEE_FLOAT ) )

この上の行で、次のようにして定数をテストしました

#define __STR2__(x) #x
#define __STR1__(x) __STR2__(x)
#pragma message __STR1__(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)

#pragma message: KSDATAFORMAT_SUBTYPE_IEEE_FLOATこれは、失敗する直前に正常に出力されます。これがコンパイラのフラグメントです

g++ -c -pipe -fno-keep-inline-dllexport -g -std=c++0x -frtti -Wall -Wextra -fexceptions -mthreads -DUNICODE -D__WINDOWS_WASAPI__ -DQT_QML_DEBUG -DQT_QUICK_LIB -DQT_GUI_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN -I..\THEPROJECT -I. -I..\THEPROJECT\thirdparty -I..\THEPROJECT\thirdparty\maximilian -IC:\Qt\5.5\mingw492_32\include -IC:\Qt\5.5\mingw492_32\include\QtQuick -IC:\Qt\5.5\mingw492_32\include\QtGui -IC:\Qt\5.5\mingw492_32\include\QtANGLE -IC:\Qt\5.5\mingw492_32\include\QtQml -IC:\Qt\5.5\mingw492_32\include\QtNetwork -IC:\Qt\5.5\mingw492_32\include\QtCore -Idebug -IC:\Qt\5.5\mingw492_32\mkspecs\win32-g++  -o debug\RtAudio.o ..\THEPROJECT\thirdparty\RtAudio.cpp
..\THEPROJECT\thirdparty\RtAudio.cpp: In member function 'virtual RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo(unsigned int)':
..\THEPROJECT\thirdparty\RtAudio.cpp:4122:57: note: #pragma message: KSDATAFORMAT_SUBTYPE_IEEE_FLOAT

これはおそらく本当にばかげた間違いですが、私はここ 2 日間ヘッドバンギングをしています。手がかりはありますか?

編集:mmreg.hの内容へのより完全な参照を含めました

4

1 に答える 1

1

この問題は、コンパイル ステートメントでライブラリが欠落していたことが判明しました。これらのライブラリは、Microsoft Visual Studio でコンパイルする場合は暗黙的であるように見えますが、MinGW でコンパイルする場合は明示的にリンクする必要があります。

を追加-lwinmm -lksuser -luuidすることで問題は解決しました。

Windows で WASAPI コントロール用に RtAudio をコンパイルする場合、これらのライブラリはコンパイルに関する RtAudio ページにリストされているため、それらを含めなかったのは愚かなエラーでした。

補足として、コンパイラ エラーは、リンク段階ではなく、RtAudio.cpp を RtAudio.o にコンパイルするときに発生するように見えるため、この明らかなリンク エラーがその段階で表示されたことに驚いています。

コメントや回答を提供してくれたすべての人に感謝します。

于 2016-02-05T14:59:02.193 に答える