🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

4回答

5785閲覧

"未定義の外部参照"というエラーの解決方法が知りたい。

退会済みユーザー

退会済みユーザー

総合スコア0

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/11/30 23:35

編集2020/12/01 00:06

以下の提示コードですが未定義の外部参照というエラーが発生してしまい困っていますどうすればいいのでしょうか?リンクエラーだと思われますがしっかりインクルードガードしています。

エラー「
LNK2019 未解決の外部シンボル "public: __cdecl Input_Key::Input_Key(void)" (??0Input_Key@@QEAA@XZ) が関数 "public: __cdecl Main_Screen::Main_Screen(void)" (??0Main_Screen@@QEAA@XZ) で参照されました

環境
Windows 10
Visual studio 2019
Debug 64ビットでビルドしています
ライブラリ OpenAL のみです : https://www.openal.org/downloads/

Github: https://github.com/Shigurechan/OpenAL

///////////ソース部

cpp

1#include "Input_Key.hpp" 2#include "KeyCode.hpp" 3 4#include <conio.h> 5#include <iostream> 6 7Input_Key::Input_Key() 8{ 9 printf("Input_Keyコンストラクタ \n"); 10} 11 12// キー入力 13KeyCode Input_Key::InputDown() 14{ 15 16 int p = _getch(); 17 if (p == 'M')//右 18 { 19 return KeyCode::Right; 20 } 21 else if (p == 'K')//左 22 { 23 return KeyCode::Left; 24 25 } 26 else if (p == 'H')//上 27 { 28 return KeyCode::Up; 29 30 } 31 else if (p == 'P')//下 32 { 33 return KeyCode::Down; 34 } 35 else if (p == ' ')//スペースキー 36 { 37 return KeyCode::Space; //スペースキー 38 } 39 else if (p == 27) 40 { 41 exit(0); 42 } 43 else 44 { 45 return KeyCode::Invalid; 46 } 47} 48

cpp

1#include "SoundPlayer.hpp" 2#include <iostream> 3#include <AL.h> 4#include <ALC.h> 5 6#include "dr_wav.h"//ライブラリのため文字数の関係で割愛 7 8//コンストラクタ 9SoundPlayer::SoundPlayer() 10{ 11 // printf("SoundPlayer コンストラクタ\n"); 12 13 wav = new drwav(); 14 15 16 17 18} 19 20void SoundPlayer::InputFile(const char* fp) 21{ 22 23 mFilePath = fp; 24 // --- バッファー 25 buffer = 0; 26 alGenBuffers(1, &buffer); 27 if (alGetError() != AL_NO_ERROR) 28 { 29 fprintf(stderr, "Couldn't generate buffer.\n"); 30 exit(1); 31 } 32 33 // --- ソース 34 mSource = 0; 35 alGenSources(1, &mSource); 36 if (alGetError() != AL_NO_ERROR) 37 { 38 fprintf(stderr, "Couldn't generate source.\n"); 39 exit(1); 40 } 41 42 43 44 45 46// std::string FilePath = "Music.wav"; //ファイル名 47 // .wavファイルを読み込む 48 49 if (!drwav_init_file(wav, mFilePath.c_str(), nullptr)) { 50 fprintf(stderr, "Couldn't load file for reading.\n"); 51 exit(1); 52 } 53 54 55 // PCMデータを読み取り、それをバッファにロードします。 56 std::vector<int16_t> sampleData;// OpenAL サンプル 57 sampleData.resize(wav->totalPCMFrameCount * wav->channels); 58 59 //オーディオのチャンクを16ビットPCMサンプルに変更します。 60 mFramesCount = drwav_read_pcm_frames_s16(wav, wav->totalPCMFrameCount, sampleData.data()); 61 62 // printf("frames: %llu\n", framesRead); 63 64 //エラー処理 65 if (mFramesCount != wav->totalPCMFrameCount) 66 { 67 fprintf(stderr, "Couldn't read file.\n"); 68 } 69 70 71 mBisPerSample = wav->bitsPerSample; //ビットパーフレーム 72 mSampleRate = wav->sampleRate; //サンプルレート 73 74 //ステレオかモノラルかを設定 75 if (wav->channels == 2) { 76 77 format = AL_FORMAT_STEREO16; 78 // printf("FORMAT_STEREO\n"); 79 } 80 else { 81 format = AL_FORMAT_MONO16; 82 // printf("FORMAT_MONO16\n"); 83 84 } 85 86 alBufferData(buffer, format, sampleData.data(), static_cast<ALsizei>(sampleData.size() * sizeof(int16_t)), wav->sampleRate); //音楽PCMデータにバッファを設定 87 88 // エラー処理 89 if (alGetError() != AL_NO_ERROR) 90 { 91 fprintf(stderr, "Could not buffer data.\n"); 92 exit(1); 93 } 94 95 96 97 98} 99 100//再生 101void SoundPlayer::Play() 102{ 103 // printf("ええええ\n"); 104 // ---------------------- 再生 順序を変えない 105 alSourcei(mSource, AL_BUFFER, buffer); //sourceを設定 106 alSourcePlay(mSource); //再生 107 // ---------------------- 108 109 int sourceState = 0; 110 /* 111 do { 112 printf("再生中"); 113 alGetSourcei(mSource, AL_SOURCE_STATE, &sourceState); //再生中かどうかを取得 114 115 system("cls"); 116 } while (sourceState == AL_PLAYING); //再生中だったらループ 117*/ 118 // 終了処理 119 drwav_uninit(wav); 120} 121 122//一時停止 123void SoundPlayer::Pause() 124{ 125 126} 127//再生終了 128void SoundPlayer::Stop() 129{ 130 131} 132 133 134//デストラクタ 135SoundPlayer::~SoundPlayer() 136{ 137 alDeleteSources(1, &mSource); 138 alDeleteBuffers(1, &buffer); 139 140} 141 142

cpp

1#include "Main_Screen.hpp" 2#include "SoundPlayer.hpp" 3#include "Input_Key.hpp" 4#include "KeyCode.hpp" 5 6 7 8 9//コンストラクタ 10Main_Screen::Main_Screen() 11{ 12 mPlayer = new SoundPlayer(); 13 mInput = new Input_Key();///これをコメントアウトすると正常にビルドできる 14} 15 16 17void Main_Screen::Update() 18{ 19 /* 20 if (mInput->InputDown() == KeyCode::Space) 21 { 22 printf("ああああ\n"); 23 } 24 */ 25 26 27} 28 29// -------------------------- ループ -------------------------- 30void Main_Screen::Loop() 31{ 32 33 const char* str = "Music.wav"; 34 mPlayer->InputFile(str); 35 mPlayer->Play(); 36 37 38 while (true) 39 { 40 Update(); 41 GenerateOutput(); 42 system("cls"); 43 } 44} 45// -------------------------- -------------------------- 46void Main_Screen::GenerateOutput() 47{ 48 49 printf("Sound Player\n\n"); 50 printf("FilePath: %s\n", mPlayer->mFilePath.c_str()); //ファイルパス 51 /* 52 if (mPlayer->wav->channels == 2) //チャンネル数 53 { 54 printf("Channels: Stereo\n"); 55 } 56 else 57 { 58 printf("Channels: Monaural\n"); 59 } 60 */ 61 62 printf("MbisPerSample: %llu bit\n", mPlayer->mBisPerSample); //ビットパーフレーム 63 printf("mSamleRate %llu Khz\n", mPlayer->mSampleRate); //サンプルレート 64 65 66 67 68}

cpp

1#include <iostream> 2#include <cstdio> 3#include <vector> 4#include <Windows.h> 5#include <AL.h> 6#include <ALC.h> 7#include "conio.h" 8 9#include "Main_Screen.hpp" 10 11// 計算 12void Update() 13{ 14 15} 16 17// 描画 18void GenerateOutput() 19{ 20 21} 22 23int main() { 24 25 ALCdevice* const device = alcOpenDevice(nullptr); //デバイス 26 ALCcontext* const context = alcCreateContext(device, nullptr); //コンテキスト 27 28 29 class Main_Screen* mc = new Main_Screen(); 30 31 32 33 34 35 // デバイスの生成エラー 36 if (device == nullptr) 37 { 38 fprintf(stderr, "Couldn't open OpenAL device."); 39 exit(1); 40 } 41 42 // コンテキスト生成エラー 43 if (context == nullptr) 44 { 45 fprintf(stderr, "Couldn't create OpenAL context.\n"); 46 exit(1); 47 } 48 49 // コンテキストを利用 50 if (alcMakeContextCurrent(context) != ALC_TRUE) 51 { 52 fprintf(stderr, "Couldn't make OpenAL context current.\n"); 53 exit(1); 54 } 55 56 57 58 mc->Loop(); 59 60 61 62 63 64 alcDestroyContext(context); 65 alcCloseDevice(device); 66 67 return 0; 68}

///////////ヘッダー部

hpp

1#ifndef ___INPUT_KEY_HPP_ 2#define ___INPUT_KEY_HPP_ 3#include "KeyCode.hpp" 4#include <iostream> 5 6class Input_Key 7{ 8public: 9 10 Input_Key(); 11 // キー入力 12 KeyCode InputDown(); 13private: 14 15}; 16 17#endif 18

hpp

1#ifndef __KEYCODE_HPP 2#define __KEYCODE_HPP 3 4 5 6//キーコード 7enum class KeyCode { 8 9 //public: 10 Left, 11 Right, 12 Up, 13 Down, 14 15 Space, 16 17 18 19 20 Invalid, 21 22}; 23 24#endif 25

hpp

1#ifndef ___MAIN_SCREEN_HPP_ 2#define ___MAIN_SCREEN_HPP_ 3 4#include "SoundPlayer.hpp" 5#include "Input_Key.hpp" 6#include "KeyCode.hpp" 7 8/******************************************* 9* メイン画面 10********************************************/ 11 12class Main_Screen 13{ 14public: 15 16 Main_Screen(); //コンストラクタ 17 void Loop(); //メインループ 18 void Update(); //計算 19 void GenerateOutput(); //描画 20 21private: 22 23 Input_Key* mInput = nullptr; //キー入力 24 SoundPlayer* mPlayer = nullptr; //音楽再生 25 26}; 27 28#endif 29

hpp

1#ifndef ___SOUNDPLAYER_HPP_ 2#define ___SOUNDPLAYER_HPP_ 3#include <iostream> 4#include <AL.h> 5#include <ALC.h> 6#include "dr_wav.h" 7 8#define DR_WAV_IMPLEMENTATION 9#include <iostream> 10#include <cstdio> 11#include <vector> 12#include <Windows.h> 13#include <AL.h> 14#include <ALC.h> 15 16#include <vector> 17 18class SoundPlayer 19{ 20public: 21 22 SoundPlayer(); //コンストラクタ 23 ~SoundPlayer(); //デストラクタ 24 void InputFile(const char* fp); //ファイル名を入力して待機 25 void Play(); //再生中 26 void Pause(); //一時停止 27 void Stop(); //再生終了 28 29 ALuint mSource = 0; // OpenAL ソース 30 31 std::string mFilePath; //ファイルパス 32 ALenum format; //チャンネル 33 drwav_uint64 mFramesCount; // PCM フレーム数 34 drwav_uint64 mBisPerSample; //ビットパーフレーム 35 drwav_uint64 mSampleRate; //サンプルレート 36 37private: 38 39 ALuint buffer = 0; // OpenAL バッファー 40 drwav* wav = nullptr; //drwavライブラリ 41 42}; 43 44 45 46#endif

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2020/11/30 23:41

ビルド設定はどのようになっていますか?
退会済みユーザー

退会済みユーザー

2020/11/30 23:47

Debug 64ビットです。
maisumakun

2020/12/01 00:02

プロジェクト内は、どのようなディレクトリ構造になっていますか?
thkana

2020/12/01 00:04

https://teratail.com/help/question-tips#questionTips3-5-1 「現象を再現するためのミニマムなプログラムを改めて作ることです。そうすれば、貴方自身が現象と問題をより良く理解することにもつながるからです。」 やってみては。(余計な?ライブラリとかあるとこちらも手元で試せないので)
退会済みユーザー

退会済みユーザー

2020/12/01 00:08 編集

OpenALを使っています。プロジェクト内はVisual studio 2019で普通にエディタ内で新しい項目を追加でヘッダーとソースファイルを作成して普通にやっています。ディレクトリ内を見ましたが他と同じようにソースとヘッダーファイルがあるのでやはりファイルは認識されていて感知されているみたいです。
maisumakun

2020/12/01 00:20

> ディレクトリ内を見ましたが他と同じようにソースとヘッダーファイルがあるので それぞれのファイルのパスを明示してください。
guest

回答4

0

1つ突っ込んでおきます。

リンクエラーだと思われますがしっかりインクルードガードしています。

インクルードガードはソースコード上の問題であって、リンクエラーと直接関連しません

投稿2020/11/30 23:42

maisumakun

総合スコア145975

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

プロパティ
Input_Key.cppのプロパティがC/C++ヘッダーになっています。

投稿2020/12/01 00:43

mah

総合スコア591

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ライブラリの指定が不足してるってことなんで、そこらへん見直してみよう

投稿2020/11/30 23:41

y_waiwai

総合スコア88038

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/11/30 23:47

どいうことでしょうか?不足してるのは自分の書いたものだと思うのですがどうすればいいのでしょうか?
y_waiwai

2020/11/30 23:54

なら、あなたの書いたものに不足してるものがあるので、 ちゃんとデバッグしましょう。 そのInput_Keyってやつ、コンパイル対象に入ってる?
退会済みユーザー

退会済みユーザー

2020/11/30 23:57

コンパイル対象に入っています。ディレクトリを確認しました。
guest

0

プロジェクトを作り直してファイルをドラックして同じことをしたらコンパイルが通りリンクも通りました。
正常にビルドでき実行できました。"結論 プロジェクトを作り治した"
イメージ説明

投稿2020/12/01 00:28

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問