質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
C++

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

DirectX

DirectX(ダイレクトエックス)は、 マイクロソフトが開発したゲーム・マルチメディア処理用のAPIの集合です。

Q&A

解決済

2回答

2278閲覧

【C++】DirectXをG++でビルドしたいが「D3D11CreateDevice」を参照できない

droid

総合スコア15

C++

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

DirectX

DirectX(ダイレクトエックス)は、 マイクロソフトが開発したゲーム・マルチメディア処理用のAPIの集合です。

0グッド

0クリップ

投稿2021/11/25 21:11

編集2021/11/26 00:21

DirectXをG++でビルドしたいのですが、DirectXを初期化しようと「D3D11CreateDevice」を呼び出すと、エラーになります。
VisualStudioでビルドすると、問題ないのですが、G++でビルドしようとすると、「undefined reference to `D3D11CreateDevice'」というエラーが発生してしまします。

G++でのビルドは不慣れなため、解決する自信があまり無いのですが、もし解決方法等にあてがあればご教示ください。

VisualStudioで「D3D11CreateDevice」のメソッドは、「C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\um\d3d11.h」を参照しているようです。
ただ、設定ファイルを見てもどうやって、それを参照しているかは不明です。

■エラーメッセージ

> make g++ -shared -O2 -o bin/XxLib.dll obj/XxLib.o obj/SystemClass.o obj/DirectXManager.o -mwindows obj/DirectXManager.o:DirectXManager.cpp:(.text+0x315): undefined reference to `D3D11CreateDevice' collect2.exe: error: ld returned 1 exit status make: *** [XxLib.dll] エラー 1

■エラーが発生している行(cppファイル)。DirectXの初期化処理。

D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, flags, nullptr, 0, D3D11_SDK_VERSION, &d3d11Device, nullptr, &m_d3d11DeviceContext);

■ビルドに使用しているMakefile

################################################## # 単一パラメータ OBJDIR = obj SRCDIR = src BINDIR = bin PROGRAM = XxLib.dll ################################################## # 複合パラメータ OBJS = $(OBJDIR)/XxLib.o $(OBJDIR)/SystemClass.o $(OBJDIR)/DirectXManager.o CFLAGS = -shared -O2 # -shared : DLL形式のライブラリ作成時に必要なコンパイルオプション # -O2 : コンパイラはサイズとコンパイル時間に妥協せずにコードのパフォーマンスを改善しようと試みる LDFLAGS=-mwindows ################################################## # make $(PROGRAM): $(OBJS) g++ $(CFLAGS) -o $(BINDIR)/$(PROGRAM) $(OBJS) $(LDFLAGS) $(OBJDIR)/%.o: $(SRCDIR)/%.c gcc $(CFLAGS) -o $@ -c $< $(OBJDIR)/%.o: $(SRCDIR)/%.cpp g++ $(CFLAGS) -o $@ -c $< ################################################## # make clean clean: del $(BINDIR)$(PROGRAM) del $(OBJDIR)*.o

■試してダメだったこと
Makefileに以下を追加してみたりしましたが、エラーは解消されませんでした。

-I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\um"

■追記(環境)
OS:Windows11
コンパイラ:MinGW(64bit版)

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

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

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

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

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

int32_t

2021/11/26 00:09

使っている g++ はどういう素性のものですか? MIngw? Mingw-w64? Cygwin?
droid

2021/11/26 00:20

最近、こちらの手順でインストールしたMinGW(64bit版)です。 1. https://www.mingw-w64.org/downloads/ より「mingw-w64-install.exe」をダウンロード、実行 2. [Next]、[x86_64][win32][sjlj]、[Next]、[Next]、[Finish] 3. 「C:\Program Files\mingw-w64\x86_64-8.1.0-posix-sjlj-rt_v6-rev0\mingw64\bin」をPathに通す
guest

回答2

0

自己解決

たくさんの方にアドバイス頂き、1人では挫折しかかっていましたが、頭の中が整理でき解決できました。
「-ld3d11」を追加することで解決しました。
また、DirectX2Dなども利用しており、他にも似たような「undefined reference to」エラーが出ましたので、「-ldxgi -ld3d11 -ld2d1 -ldwrite -lWindowsCodecs -lole32」をリンクさせるようにしました。

Makefile

1################################################## 2# 単一パラメータ 3OBJDIR = obj 4SRCDIR = src 5BINDIR = bin 6PROGRAM = UqLib.dll 7 8################################################## 9# 複合パラメータ 10OBJS = $(OBJDIR)/UqLib.o $(OBJDIR)/SystemClass.o $(OBJDIR)/DirectXManager.o $(OBJDIR)/GraphicsManager.o $(OBJDIR)/FileManager.o $(OBJDIR)/Logger.o 11CFLAGS = -shared -O2 12# -shared : DLL形式のライブラリ作成時に必要なコンパイルオプション 13# -O2 : コンパイラはサイズとコンパイル時間に妥協せずにコードのパフォーマンスを改善しようと試みる 14 15LIBS = -ldxgi -ld3d11 -ld2d1 -ldwrite -lWindowsCodecs -lole32 16LDFLAGS=-mwindows 17################################################## 18# make 19 20$(PROGRAM): $(OBJS) 21 g++ $(CFLAGS) -o $(BINDIR)/$(PROGRAM) $(OBJS) $(LDFLAGS) $(LIBS) 22 23$(OBJDIR)/%.o: $(SRCDIR)/%.c 24 gcc $(CFLAGS) -o $@ -c $< 25 26$(OBJDIR)/%.o: $(SRCDIR)/%.cpp 27 g++ $(CFLAGS) -o $@ -c $< 28 29################################################## 30# make clean 31 32clean: 33 del $(BINDIR)$(PROGRAM) 34 del $(OBJDIR)*.o

途中で、「.a」ファイルの作成方法も調査しましたが、それはやらなくても良いようでした。
動作確認としては、DirectX2Dで線を引くところまでです。
(文字列表示などは、別のエラーになるので、一旦後回しにしました)

■ 補足
g++でビルドする際に$(LIBS)を記載する位置が非常に重要で、間違えると「undefined reference to」エラーになります。今回、最初にはまった一因でもあります。
【成功】g++ $(CFLAGS) -o $(BINDIR)/$(PROGRAM) $(OBJS) $(LDFLAGS) $(LIBS)
【失敗】g++ $(LIBS) $(CFLAGS) -o $(BINDIR)/$(PROGRAM) $(OBJS) $(LDFLAGS)

投稿2021/11/26 06:22

編集2021/11/26 06:31
droid

総合スコア15

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

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

Serbonis

2021/11/26 12:45

解決後ですが参考まで。 MinGWにx86_64-w64-mingw32というフォルダがあるかと思います。そこのlibフォルダ以下にlibaxxx.a形式のライブラリが入っていると思います。-Lオプションでそこにパスを通すか、環境変数LIBRARY_PATHに設定すればよいかと思います。
droid

2021/11/26 16:12 編集

ご教授頂き、ありがとうございます。 確かに、以下のlibフォルダ配下にlibaxxx.a形式のライブラリが格納されておりました。 C:\Program Files\mingw-w64\x86_64-8.1.0-posix-sjlj-rt_v6-rev0\mingw64\lib 情報共有いただきありがとうございます。 ただ、私がMinGWを初めて使っているので、パスの通しかた、環境変数の設定方法、それによって何が変わるのか分かっておりません。MinGWもしっかり勉強すると奥が深いと思いました。
guest

0

ググっただけですが、こちらが参考にならないでしょうか?

■ Creating correct D3D11 library file for GCC
https://stackoverflow.com/questions/26722643/creating-correct-d3d11-library-file-for-gcc

投稿2021/11/25 22:59

cx20

総合スコア4633

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

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

droid

2021/11/25 23:45

そちらのURLですが、調査時に確認はしておりました。 「DirectXSDKで提供されているd3d11.libのようなファイルを* .a GCCライブラリ形式に変換する正しい方法」 今回のエラーが「undefined reference to `D3D11CreateDevice'」です。 そして、「D3D11CreateDevice」はメソッドであり、d3d11.hに記載があることまでは理解しています。 まず、わからないのが「d3d11.lib」の中にd3d11.hが含まれているものなのでしょうか? また、GCCでビルドするときには、「d3d11.lib」や「d3d11.h」がどう関わってくるのか、わかっていません。 そのため、「d3d11.libのようなファイルを* .a GCCライブラリ形式に変換」のQ and Aを見ても、何が何だか分からないという状況です。
droid

2021/11/26 01:09 編集

d3d11.lib の中には、「D3D11CreateDevice」はあるようでした。 また、d3d11.libは「C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\um\x86\d3d11.lib」にあるようでした。 まず、d3d11.libをgccでビルドするときに、どう関連付ければ良いのでしょうか? また、d3d11.libだけ関連付ければ、d3d11.hは不要でしょうか? ■ d3d11.libをdumpしたもの ``` Dump of file C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\um\x86\d3d11.lib File Type: LIBRARY Exports ordinal name _CreateDirect3D11DeviceFromDXGIDevice@8 _CreateDirect3D11SurfaceFromDXGISurface@8 _D3D11CoreCreateDevice@40 _D3D11CoreCreateLayeredDevice@20 _D3D11CoreGetLayeredDeviceSize@8 _D3D11CoreRegisterLayers@8 _D3D11CreateDevice@40 _D3D11CreateDeviceAndSwapChain@48 _D3D11On12CreateDevice@40 Summary BD .debug$S 14 .idata$2 14 .idata$3 4 .idata$4 4 .idata$5 A .idata$6 ```
退会済みユーザー

退会済みユーザー

2021/11/26 00:24 編集

> そちらのURLですが、調査時に確認はしておりました。 こういう事があって二度手間になるので、自分で調べたサイトくらいは質問に記載しておいたほうがいいですよ。
droid

2021/11/26 00:25

次回より、気を付けます。すみませんでした。 ただ、そちらのサイトを試せたわけではなく、今は「09:07」のような理解でとどまっています。
退会済みユーザー

退会済みユーザー

2021/11/26 00:33 編集

試してないなら余計に悪いです。自分で最低限試せる事を試してから質問しましょう。 [1-2. 投稿前に検索し、できるところまで自分でやってみましょう] https://teratail.com/help/question-tips#questionTips1-2 "g++ directx11" "gcc directx11" でググるだけでもそれっぽい記事はヒットしますけど、そういったものは一通り確認して試したりしましたか?
droid

2021/11/26 00:33

試しに「-ld3d11」と「 -L"/Program Files (x86)/mingw-w64/i686-8.1.0-posix-dwarf-rt_v6-rev0/mingw32/lib"」を追加して、ビルドしてみましたが、エラーは変わらず「undefined reference to `D3D11CreateDevice'」でした。 ``` g++ -ld3d11 -L"/Program Files (x86)/mingw-w64/i686-8.1.0-posix-dwarf-rt_v6-rev0/mingw32/lib" $(CFLAGS) -o $(BINDIR)/$(PROGRAM) $(OBJS) $(LDFLAGS) ```
droid

2021/11/26 00:35

「"g++ directx11" "gcc directx11"」はググっていませんでした。 今から確認します。
droid

2021/11/26 01:45 編集

「g++ directx11」でググったところ、「https://sirocco.hatenadiary.org/entry/20090508/1241755577」によると、 「reimp : MSのツールで作ったライブラリを mingw32、cygwin から使えるようにするためのツールらしい。」という情報を見つけました。 d3d11.lib がMSのツールで作ったライブラリなのかもしれませんので、とりあえず「libd3d11.a」を作るところまでは成功しました。 ■ 1. d3d11.def作成 作業 https://pzuk-wordpress-com.translate.goog/2012/03/28/153/?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja&_x_tr_pto=nui,sc を参考に 「https://sourceforge.net/projects/mingw/files/MinGW/Extension/mingw-utils/mingw-utils-0.3/mingw-utils-0.3.tar.gz/download」 より「mingw-utils-0.3.tar.gz」をダウンロード。 Powershellで、「tar -xzf mingw-utils-0.3.tar.gz」で解凍。 →「bin\reimp.exe」などが使えるようになった。 コマンドプロンプトを起動し、binフォルダが存在するフォルダに移動し $ bin\reimp -c -d "C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\um\x86\d3d11.lib" → d3d11.defが作成された ■ 2. libd3d11.a 作成 作業 https://tsubaki.hatenablog.com/entry/20110115/1295080728 を参考に 管理者権限でコマンドプロンプト起動 $ cd "C:\Program Files\mingw-w64\x86_64-8.1.0-posix-sjlj-rt_v6-rev0\mingw64\bin" [1]で作成した「d3d11.def」をこのbinフォルダにコピー $ dlltool -d d3d11.def -l libd3d11.a → 「libd3d11.a」が作成された ー------------------------------ 現在は、作成した「libd3d11.a」をどう利用するのかというところで詰まっております。
退会済みユーザー

退会済みユーザー

2021/11/26 01:52

そのへんの試した事、詰まった所を質問を編集して追記してください。
droid

2021/11/26 02:01 編集

Makefileを以下のように「-ld3d11」追記で修正したら、「libd3d11.a」を使わなくてもg++ビルドが通りました。 【修正前】g++ $(CFLAGS) -o $(BINDIR)/$(PROGRAM) $(OBJS) $(LDFLAGS) 【修正後】g++ $(CFLAGS) -o $(BINDIR)/$(PROGRAM) $(OBJS) $(LDFLAGS) -ld3d11 一旦、最初に直面したエラーは解消できました。(対処法として正しいかは、画像表示をするところまでコーディングをちゃんとして動けば正しいと思いますが、まだ未確認です)
droid

2021/11/26 02:00

> そのへんの試した事、詰まった所を質問を編集して追記してください。 「libd3d11.a」を使わないでも「-ld3d11」の付与だけでうまくいく可能性が出てきましたので、いったんこちらで最後までコーディングして、動作確認してみます。 うまくいったら、質問を編集して、どう解決したか記載するようにします。
退会済みユーザー

退会済みユーザー

2021/11/26 02:35

もし自力で解決できましたら、対処法を自己回答してベストアンサーに選択すればOKです。
droid

2021/11/26 04:26

現状、矩形表示などのサンプルを実装しましたが、何も表示されません。 DirectXの初期化はうまくいったのか、背景は黒くなりました。 やはりVisualStudioでビルドできても、MinGWでのビルドには簡単に切り替えられないようです。 「g++ directx11」で検索して、もう少し動きそうなサンプルを探してみます。 といのも、「-ld3d11」の対応が正しかったかが、エラーがなくなっただけだと、まだ不明だからです。 こういう場合、質問をいつまでオープンしておくかも難しいです。
退会済みユーザー

退会済みユーザー

2021/11/26 04:44 編集

まあ、ビルドとDirectXの初期化に成功しているのであれば、とりあえず質問のタイトルの問題は解決したのではないでしょうか。インポートライブラリはDLLの関数を呼び出すためのものなので、DLLや、DLLに呼び出している関数そのものが見つからなかった場合は、実行時に即座にエラーになり停止します。 既存の処理が表示されるされないはまた別の問題なので、必要最小限のサンプル作ってみたり、地道に変数やエラーコードのログ取ったりして調べていくしかないですね。
droid

2021/11/26 06:26

「g++ directx11」のキーワードは非常に助かりました。 ありがとうございました。無事に線の描画までは成功しました。
cx20

2021/11/27 01:46

すみません、外出中で返信が出来ませんでした。 解決されたようで何よりです。 自分もg++に詳しい訳では無いので、調査された結果については参考になります。情報ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問