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

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

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

VC++ (Visual C++) とは、Microsoft製のC++のための統合開発環境です。

HLSL

HLSLは、米マイクロソフト社によって開発された Direct3D APIで使われるプロプライエタリなシェーディング言語です。

Q&A

1回答

367閲覧

C++のスタティックリンクライブラリ内で、そのライブラリのフォルダにあるHLSLファイルのパスを指定する方法を知りたい

kamozaka

総合スコア12

VC++

VC++ (Visual C++) とは、Microsoft製のC++のための統合開発環境です。

HLSL

HLSLは、米マイクロソフト社によって開発された Direct3D APIで使われるプロプライエタリなシェーディング言語です。

0グッド

0クリップ

投稿2023/11/05 02:03

編集2023/11/05 03:32

環境:Visual Studio Community 2022

DirectX9でプログラマブルシェーダを使用するため、D3DXCreateEffectFromFile()にHLSLファイル(今回は拡張子fx)のパスを指定する必要があります。
単一のアプリの場合は、プロジェクトフォルダにfxファイルを置いた上で、D3DXCreateEffectFromFile()に"example.fx"のようにファイル名だけを指定すれば問題ありません。

しかし、このプログラマブルシェーダ使用部分をスタティックリンクライブラリ化した所、パスの指定をどうすべきかという問題が生じました。

状況:
・fxファイルのパスを指定するD3DXCreateEffectFromFile()をライブラリ内で使用する。
・fxファイルも同じライブラリの一部であり、C++のソースファイルと同じくライブラリのフォルダ内にある。

この場合、このファイルのパスを指定するには、どのようにするのが最適なのでしょうか?
普通によくある状況だろうと思いますが、皆さんはどのように設定されているのでしょうか。

検討した選択肢

(1) ファイル名だけを指定 → ✕
最初の状態です。アプリのプロジェクトは、そのプロジェクトのフォルダにfxファイルがあれば認識してくれますが、そこにない場合はD3DXCreateEffectFromFile()が失敗するため、何らかの対応が必要となりました。

(2) 絶対パスを指定 → △
ライブラリフォルダ内のfxファイルの絶対パスを指定する方法です。
とりあえずはこれで動きましたが、ライブラリのパスが変化すると破綻するので、暫定措置とみなしたい方法です。
また、書いているソースコードと同じ場所であるにも関わらず、それを指定するのにわざわざ絶対パスを使用している、という点も違和感があります。

(3) アプリからの相対パスを指定 → △
アプリフォルダからの相対パス(例えば「../../LIB/~」のような)を指定する方法です。
これでも動きましたが、当然ながら「ライブラリ内に特定アプリからの相対パスを書く」というのは論外です。

(4) 「ライブラリ ディレクトリ」を使用(したいが未達成)
Visual Studioがマクロ$(LibraryPath)として認識している「ライブラリ ディレクトリ」からの相対パスなら認識してくれるのでは?と期待したのですが、ダメでした。例えば$(LibraryPath)が表すパスにfxファイルを置いても認識してくれません。
ならば、C++内から$(LibraryPath)の値を取得できればfxファイルのパスを生成できそうですが、取得する方法が分かりませんでした。
もしそれが可能なのであれば、これが最適解になるのでしょうか?

(5) ライブラリプロジェクトへの追加 → ✕
ライブラリプロジェクト(これは常にアプリのソリューションに含めることにしています)の構成ファイルにしてあれば、"example.fx"というファイル名だけの指定でも認識してくれないかな?と期待したのですが、ダメでした。
(ちなみに、単に追加するだけだとコンパイルエラーになるので、試すにはfxファイルのプロパティで「ビルドから除外」を「はい」にする必要がありました。)

(6) fxファイルの内容をC++ファイル内に埋め込む → △
fxファイルを使うのをやめ、D3DXCreateEffectFromFile()ではなくD3DXCreateEffect()を使って、HLSLによる記述をC++ファイル内で文字列リテラルとして記述する方法です。
しかし、この方法はHLSL部分の編集がしづらくなります。ごく短いコードならともかく、ある程度の長さがある場合は、HLSLは外部ファイルにしておきたいです。

(7)ビルドイベントで何とかする → △
例えば、アプリのプロジェクトのビルドイベントに「fxファイルを自プロジェクトのフォルダにコピーする」のような処理を記述するという、強引なやり方です。
やりたくないですが、思いついたので一応…。

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

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

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

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

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

setoppu

2023/11/05 03:27

そのライブラリとやらはDLLってことでいいんですかね? LoadLibrary()/LoadLibraryEx()での読み込みの場合、 GetModuleFileName()辺りで、ライブラリのフルパスが取得できませんかね?
kamozaka

2023/11/05 03:33

コメントありがとうございます。 > そのライブラリとやらはDLLってことでいいんですかね? あ、言葉足らずですみません。 DLLではなくスタティックリンクライブラリです。本文にも追記しました。 DLLの場合はそのような方法があるのですね。覚えておきます。
dameo

2023/11/05 08:55

■各プロジェクトの出力ファイルについて もし*.fxが実行時に必要なのであれば、ビルドイベントで出力ディレクトリにcopy「しないといけません」。 copy $(ProjectDir)\hoge.fx $(TargetDir) 実行時のディレクトリ構成が固定で決まっていて、そのまま実行したいのであればビルドイベントでディレクトリも掘ってそこにcopy「しないといけません」。 ■実行時にパスが必要になるAPIを呼ぶ場合 基本的にはフルパスにする必要があります。 例外としてカレントディレクトリが変更されない場合、(カレントディレクトリからの)相対パスで指定可能です。 典型的なカレントディレクトリは実行可能ファイルがある場所です。 なので、DLLであれEXEであれ、GetModuleFileName()でフルパスを頂いてそのディレクトリを取得し、hoge.fxのフルパスにすれば、.DLL,.EXEと同じディレクトリに置くルールで運用可能です。 普通はそれだとアプリやDLL側で困るので、アプリ/DLL側からパスを指定可能にすると思います。 別に難しいことではなく、普通のテキストファイルを読み込むだけでも同じですよ。
guest

回答1

0

DirectXは知らないのですが、
「スタティックライブラリにしたい関数でファイルを読む必要があるが、そのファイルは関数固有のものなので、呼ぶ側で指定する物では無い」ということですかね。
であれば、私なら(6)で、ライブラリ関数のコーディングは別ファイルで行って、ライブラリビルド時にソースに自動的に埋め込んでからコンパイルですかね。

タイトルの

スタティックリンクライブラリ内で、そのライブラリのフォルダにあるHLSLファイルのパスを指定する方法

は原理的に不可能ですね。スタティックリンクの一般論で言うと、実行マシンに「そのライブラリのフォルダ」が存在しないことも多いわけだし。

投稿2023/11/05 16:48

otn

総合スコア84633

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問